Binary Indexed Tree, BIT ( Single Point Modification, Interval Summation )

Why to use

  • More quick, more fast

  • Apply to interval summation, so if you use array ( O(n2)O (n^2) ) or prefix-summation ( modification O(n)O(n) , query of interval summation O(1)O(1) ), so when the nn is very big, it will be slow.

Binary Indexed Tree

Operations

  1. add(i,k)add ( i , k )     \space\space\space\space ( 1in1\le i\le n )     \space\space\space\space add kk to the values of ii elements

  2. sum(i)sum (i)     \space\space\space\space ( 1in1\le i\le n )     \space\space\space\space calculate the sum of range (1,i)(1,i)

Basic Properties

  1. Firstly, BIT is a kind of array, also a kind of tree.

  2. Secondly, BIT stored in memory as an array.

  3. Thirdly, for two array index x , yx\space ,\space y, if x+2k=yx + 2^k = y ( k is the number of 0 of (x)2(x)_2 ), so we define (y,x)(y,x) is a couple father and son on tree. In this, y is the father, x is the son.

Store

image.png

Like this. cic_i shows son-tree's leaves summation.

So:

c1c_1 = a1a_1

c2c_2 = a1a_1 + a2a_2

c3c_3 = a3a_3

c4c_4 = a1a_1 + a2a_2 + a3a_3 + a4a_4

c5c_5 = a5a_5

c6c_6 = a5a_5 + a6a_6

c7c_7 = a7a_7

c8c_8 = a1a_1 + a2a_2 + a3a_3 +a4a_4 + a5a_5 + a6a_6 + a7a_7 + a8a_8

If we change the array-cc to binary:

(1 = 001)

(2 = 010)

(3 = 011)

(4 = 100)

(5 = 101)

(6 = 110)

(7 = 111)

(8 = 1000)

We could find out that: ci=ai2k+1+ai2k+2+...+aic_i = a_{i-2^k+1} + a_{i-2^k+2} +...+a_i (kk is the binary of ii the successive 00 from low-digit to high-digit)

BIT Query Intercal Summation

sum7=c4+c6+c7sum_7 = c_4 + c_6 + c_7

eqauls

sum(111)2=c(111)2+c(110)2+c(100)2sum_{(111)_2} = c_{(111)_2} + c_{(110)_2} + c_{(100)_2}

  • So, we could add some elements of array cc to get the intercal summation.

  • lowbit (i)

    Get the value of 2k2^k. kk is the binary of ii the successive 00 from low-digit to high-digit.

  • While the nn is more bigger, BIT's goodness is more clearly.

  • We can "minus" the 00 at the end of the binary of ii, that means we need to minus 2k2^k.

inline int sum ( int x ) {
    int ans = 0 ;
    while ( x > 0 ) {
        ans += c[x] ;
        x -= lowbit (x) ;
    }
    return ans ;
}

BIT Single Point Modification

  • While we change array aa, we need to update array cc. It will be a reverse process of sum(i).
inline void add ( int x , int d ) {
    while ( x <= n ) {
        c[x] += d ;
        x += lowbit (x) ;
    }
}

Time Complexity

Modification & Summation

  • In add ( x , d ), we need add dd to each cic_i interval containing axa_x. As same as in sum (x), we need to count the sum of O(logn)O(\log n) intervals.

  • In lowbit (x), every time you deal with an interval, you need a lowbit (x) function. So it's O(logn)O(\log n) too.

Lowbit Function

  • Simple version of lowbit (x) function:
inline int lowbit ( int x ) {
    int ans = 1 ;
    while ( x % 2 == 0 ) {
        x /= 2 ;
        ans *= 2 ;
    }
    return ans ;
}

Summary

So, if you use the simple version of lowbit (x) function, the sum time complexity will be O(log2(n))O(\log^2 (n))

More Quick Of Lowbit

  • We can use complement code to calculate it.

  • Code:

inline int lowbit ( int x ) {
    return x & -x ;
}
  • So now the time complexity is O(logn)O(\log n), memory complexity O(n)O(n).

BIT Extention

Interval Modification, Single Point Query

  1. add(x,y,k)add ( x , y , k )     \space\space\space\space ( ai+=ka_i += k , xiyx\le i\le y )     \space\space\space\space add kk to the elements in interval [x,y][x,y].

  2. get(x)get (x)     \space\space\space\space ( print axa_x )     \space\space\space\space query the value of element xx.

Single Point Modification & Interval Modification
  • We can use difference to solve this problem, turn what array element sumnsum_n wants to the value of ana_n. Solution like the down text.

  • We use array bb to:

    • If nn eqauls 11, b1=a1b_1 = a_1

    • If n>1n > 1, bn=anan1b_n = a_n - a_{n-1}

    • We get array sumsum use BIT on array bb, then sumn=ansum_n = a_n

Single Point Query & Interval Summation
  • Like last page, it also can use difference to solve the problem.

  • We don't need every elements add on a kk. You see, ai=b1+b2+...+bia_i = b_1 + b_2 + ... + b_i, when we add kk on left, we just need to add only one k on right to keep it's balance.

  • So, if we want to add k on the elements of axa_x to aya_y, we should: bx+=k;by+1=k;b_x += k; b_{y + 1} -= k;.