学习树状数组必不可少学习树状数组的精髓,lowbit()运算
在计算机中存储一个正数是以二进制的形式,而存储一个负数则是以二进制补码的形式,简单说就是二进制取反+1,lowbit运算就是提取出最后一个1以后的位置,比如10100进行lowbit运算就是100,11010进行lowbit运算就是10,在写的时候lowbit就是x&(-x),可以随便造几个数来看一下效果,假设x的二进制是10100,x的反码就是01011,加1以后就是01100,x&(-x)=100,这显然不是巧合。
而树状数组就是通过lowbit运算来存储前缀和,当然lowbit运算中不能有0的存在
如图
在树状数组中,c[i]记录的是从i-lowbit(i)+1到i的和,因此单点修改,区间查询就是更改单点开始的所有lowbit即可,查询区间也是查询所有的lowbit,一维二维同理,二维就是循环两层
如果是区间修改,区间查询,可以借助一个新的差分数组d,可知d[1]=a[1],d[2]=a[2]-a[1],d[3]=a[3]-a[2],这里要求的是a数组的前缀和,那么a[1]=d[1],a[2]=d[1]+d[2],a[3]=d[1]+d[2]+d[3]...a数组前缀和就是a[1]=d[1],a[1]+a[2]=2*d[1]+d[2],a[1]+a[2]+a[3]=3*d[1]+2*d[2]+d[3]...通过归纳可以发现a[1~x]的和就等于
也就是
从这就能看出,树状数组此时需要维护两个区间,一个是差分数组d,一个是i*d
一些树状数组模板+模板题:
一维二维树状数组模板题加题解
一维二维树状数组模板(进阶版)
难点-树状数组
树状数组求逆序数