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;
    }
};

Comments