这里有一个数组(假设其无限大),我们需要进行两个操作
(1)修改其中某个元素的数值
(2)求出前n个元素的和
原理:
1
我们可以先把它提前进行相加(类似于前缀和)
这样相加时时间减少了一半,修改时只需要多更改一个数字而已,但是依旧很慢
2
我们在1的基础上,多加几层
如我们要计算前2个和前3个的时候不能用 5 这个数字,且在计算前4与前5的时候使用上面的 19 更好
所以说 5 根本不需要存在
依次类推,数组中用很多这样没必要存在的数据
后面我们发现,所有层的第偶数个数字都是没用的,即使去掉也不影响我们计算
然后我们观察之后的数据,剩下的数据个数刚好时偶数个
将这些数组转入一个新的数组中,此时这个数组就是一颗树状数组
下面的每一个区间表示的是原数组的某个区间和
我们在求和时只需要找到对应的区间,将整型区间相加即看找到答案,我们修改某个数据时,
我们要也只需要向上找到包含它的区间进行修改即可
lowbit操作
非负整数n在二进制表示下最低位1及其后面的0构成的数组
如:lowbit(44)=lowbit((101100)2)=(100)2=4
为了求这个数值
101100 //先进行按位取反
010011 //在进行加 1
010100 //此时除了最低位的1和后面的0 其他的数与原来的数都不相同
进行按位与后
101100
010100
变为 000100 变为 4
但是又因为,计算机存储时使用的时补码
我们对整数取反的话,得到的就是一个负的
所以说我们对一个数进行取反加1就等于负的这个数
即 ~n+1=-n
总的来说
lowbit(n)=n&(-n+1)
=n&-n
我们可以发现t[len]覆盖的长度就是lowbit(x),即在len为几就覆盖了几个数
而且整颗树的深度为 logn+1