Range Sum Query - Mutable 精简无递归线段树

操作: 

单点更新,区间求和

区间求和:如sum [3,10) 需要对19,5,12,26节点求和即可。

观察可知,左端点为右子节点(奇数)时直接相加,右端点为左子节点(偶数)时直接相加,两边向中间移动并求其父节点。

 1 class NumArray {
 2 public:
 3     NumArray(vector<int> nums) {
 4         n = nums.size();
 5         tree.resize(n * 2); // 满二叉树
 6         buildTree(nums);
 7     }
 8 
 9     void buildTree(vector<int>& nums) {
10         for (int i = n; i < n * 2; ++i) {
11             tree[i] = nums[i - n];
12         }
13         for (int i = n - 1; i > 0; --i) {
14             tree[i] = tree[i<<1] + tree[i<<1|1];
15         }
16     }
17 
18     void update(int i, int val) {
19         tree[i += n] = val;
20         while (i > 0) {
21             tree[i / 2] = tree[i] + tree[i^1];
22             i /= 2;
23         }
24     }
25 
26     int sumRange(int i, int j) { 
27         int sum = 0;
28         for (i += n, j += n; i <= j; i /= 2, j /= 2) {
29             if ((i & 1) == 1) sum += tree[i++];
30             if ((j & 1) == 0) sum += tree[j--];
31         }
32         return sum;
33     }    
34 
35 private:
36     int n;
37     vector<int> tree;
38 };

Refer:

Codeforces blog

猜你喜欢

转载自www.cnblogs.com/demian/p/11253670.html