Introduction
A good tutorial is here: http://community.topcoder.com/tc?module=Static&d1=tutorials&d2=binaryIndexedTrees
Imagine that we have an array A[N]
, where we do lots of interval sum operations but only a few modifications . Then it is too costy to do a sweep through the array for sum.
The binary indexed tree c[N]
is designed for this scenario, where we can enjoy a summation. However, the tradeoff is that the time complexity of modification increases from to .
Interval Summation
We use c[i]
keeps the sum , where . So for example, A[1...1101] = c[1101] + c[1100] + c[1000]
. Here the summation operations only require the number of ‘1’s in the binary representation of i
, which is .
Update
However, if we want to add a value to some postion i
, we have to update all c[k]
, where . As , the binary representation of cannot have any postions to be 1 below bit lowbit(i)
. Combined with the fact , after updating c[i]
itself, the next postion we have to update is i + lowbit(i)
, which is greater than and has no bits being 1 below lowbit(i). Then we repeat this procedure, until reach beyond the maximum number of elements .
Query
Query of a single element at a certain postion i
can be done by sum(i) - sum(i-1)
, which is .
Code
class BinaryIndexedTree{
public:
vector<int>c;
int n;
BinaryIndexedTree(int n){
this->n = n;
c.resize(n + 2, 0);
}
int lowbit(int k){
return k & (-k);
}
void modify(int pos, int v){
while(pos <= n){
c[pos] += v;
pos += lowbit(pos);
}
}
int sum(int pos){
int ans = 0;
while(pos > 0){
ans += c[pos];
pos -= lowbit(pos);
}
return ans;
}
};