Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive.
The update(i, val) function modifies nums by updating the element at index i to val . Example:
Given nums = [1, 3, 5] sumRange(0, 2) -> 9 update(1, 2) sumRange(0, 2) -> 8
Note:
- The array is only modifiable by the update function.
- You may assume the number of calls to update and sumRange function is distributed evenly.
#include <vector>
#include <iostream>
using namespace std;
// this is actually to use binary index tree.
int getSum(vector<int>& BITree, int index) {
int sum = 0;
index = index + 1;
while(index > 0) {
sum += BITree[index];
index -= index & (-index); // update to its parent node in getSum view.
}
return sum;
}
void updateBITree(vector<int>& BITree, int index, int val) {
index = index + 1;
while(index < BITree.size()) {
BITree[index] += val;
index += index & (-index); // update to its parent node in update view
}
}
vector<int> createBITree(vector<int>& nums) {
int n = nums.size();
vector<int> BITree(n + 1, 0);
for(int i = 0; i < n; ++i) {
updateBITree(BITree, i, nums[i]);
}
return BITree;
}
int main(void) {
vector<int> nums{1, 3, 5};
vector<int> BITree = createBITree(nums);
updateBITree(BITree, 1, 2);
cout << getSum(BITree, 2) << endl;
}
Let's use an example to help explain how to organize a binary index tree.
Suppose we have a 10 size array [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Our target tree will be like this:
The picture above shows how is the binary index tree organized. There are several things to pay attentions to:
1: Update parent node is index += index & (-index)
2: GetSum parent node is index -= index &(-index)
3: BITree's first index is empty.
4: The parent index equals to change the child index's rightmost bit '1' into '0'.