树状数组

  1. 树状数组引入:

给出一个数组A:A[1]~A[10000];

给出多个查询区间[L~R],求区间和;

     L  R

E1:  3 - 10000

E2:  5 - 9999

直接使用原数组时间复杂度肯定很高

引入前缀和

S[L]=A[1]+A[2]+…+A[L];

S[R]=A[1]+A[2]+...+A[R];

求区间和就好求了许多

E:A[L]~A[R]的和

= S[R]-S[L-1];

看起来挺好,用起来很是方便,可是它也有不太好的地方,如果有修改的话,每次修改就要把修改数及其之后的前缀和全部修改,那么针对需要修改的题来说这个效率又变得很低

 

 

X  

Lowbit

十进制

二进制

(末尾0个数)

子叶数

C[4]

100 2 2^2

C[3]

011 0 2^0

C[2]

010 1 2^1

C[1]

001 0 2^0

 

 

 

 

 

 

 

Lowbit:其实是求一个非负整数n在二进制表示下“最低位1和其后边0”构成的数值。

树状数组

C[i]代表从A[i-2^x+1]+…+A[i]

Lowbit(x)

Return x&(-x);

求解 E:10101000  经过Lowbit计算之后得到00001000

(取反:一个数的二进制表示法下从左向右数遇到的第一个1和所有0保持不变,向右的其余数字一次取反)

(按位与运算:1&1=1   1&0=0   0&1=0   0&0=0 )

设n>0,n的第k位为1,0~k-1位都是0,取反之后1右边的数字取反,0到k位保持不变。按位与运算之后0到k位仍然不变

以上是关于Lowbit()函数的解释,关于求和和更新的函数贴个解析:

https://blog.****.net/qq_40938077/article/details/80424318