一、树状数组的定义
引理1 下列函数lowbit
int lowbit(int x) { return x & (-x); }
能够返回数x的二进制最低位1对应的值。(例如,lowbit(10011010000)=10000。)
证明:设x的最低位的1在第k位(x=...1000...000)。则-x=~x+1=(...0111...111+1)=...1000...000。也就是说,~x在+1时,前(k-1)位一直进位,直到第k位时,由于~1=0,进位结束,且第k位仍为1。由于进位结束,则k位以上变为原来的反码。因此,x与-x仅有第k位一位相同。证毕。
定义1 树状数组第i个元素c[i]定义为
,其中
为从
往下枚举到
最后一个连续满足lowbit(j)<=lowbit(i)的j。
例如当i=6,lowbit(6)<=lowbit(6), lowbit(5)<=lowbit(6),而lowbit(4)>=lowbit(6),故k=5。尽管lowbit(1)<=lowbit(6),但不满足“连续”,故k≠1。
![线段树示意图(来自Bing图片)](https://i-blog.csdnimg.cn/blog_migrate/0c0d6d3d02439c64617f2a33da36a1fa.jpeg)
二、树状数组的求和操作
定理1
。
证明:根据树状数组的定义,c[k]为从k开始向下连续满足lowbit(i)<=lowbit(k)的a[i]的和。只需证对于c[k],这些元素的个数(设为p)为lowbit(k)。
① 先证lowbit(k-lowbit(k))>lowbit(k)。如果这个结论成立,那么p<=k-lowbit(k)。根据lowbit函数的定义,设k的二进制的最低位1在第u位,则k的第1~(u-1)位为0。那么,k-lowbit(k)的第u位为0。故k-lowbit(k)的第1~u位为0,lowbit(k-lowbit(k))>lowbit(k)。
② 再证,,
。仍设k的二进制的最低位1在第u位,设i=k-w,则当0<=w<lowbit(k)时,减法不会借位,k-w的第1~u位组成的数小于lowbit(k)。于是k-w的1~u位的最高位1所在的位小于等于u,因此lowbit(k-w)<=lowbit(k)。
定理1证毕。
由此我们可以写出如下的求和代码:
int getsum(int x) // sum[1, 2, ..., x]
{
int ans = 0;
for(int i = x; i; i -= lowbit(i))
{
ans += c[i];
}
return ans;
}
三、树状数组的单点更新操作
定理2 若给a[x]加一个数v,则下列函数update能够将c数组更新至正确的值。
void update(int x, int v) { for(int k = x; k <= n; k += lowbit(k)) { c[k] += v; } }
证明:只需更新满足k-lowbit(k)<x<=k的c[k]即可。
① 先证对于所有update函数中更新的c[k],都有k-lowbit(k)<x<=k。其中x<=k是显然的,因为在for循环中k值单调递增。对于k-lowbit(k)<x,我们可以把问题转化为证明对于任意i,令r=i+lowbit(i),有i-lowbit(i)>=r-lowbit(r)。设i的二进制的最低位1在第u位,则i+lowbit(i)的二进制的最低位1所在的位一定大于u(因为1+1=10)。将原式变形,得到lowbit(r)-lowbit(i)>=r-i,即lowbit(r)>=2*lowbit(i)。根据lowbit函数的定义以及r的最低位1所在的位数比i的最低位1所在的位数高,可以知道这个式子成立。
② 下面证update函数没有遗漏任何一个满足k-lowbit(k)<x<=k的k。首先,k必须满足k>=x。其次,要满足k-lowbit(k)<x,必须满足lowbit(k)>=lowbit(x)。理由如下:设x的二进制的最低位1所在的位为u,并设,其中
为k的低(u-1)位,
是k的第u及以上的位,|为按位或运算。又设
,其中
是x的第u及以上的位,
。那么根据k>=x,必然有
。倘若lowbit(k)<lowbit(x),则
,那么k-lowbit(k)>=x,与要求矛盾。由以上讨论可知,update函数的任务是求出所有满足k>=x且lowbit(k)>=lowbit(x),k-lowbit(k)<x<=k的k。因此,只需证明,对于任意k,下一个满足条件的k为k+lowbit(k)。即证:对于k和k+lowbit(k)之间的数b,都有b-lowbit(b)>=x。我们知道k-lowbit(k)<x。那么,只需证k-lowbit(k)<b-lowbit(b),即k-b<lowbit(k)-lowbit(b)。显然lowbit(b)<lowbit(k),因为设k的二进制的最低位1在第u位,则由
知b的后(u-1)位一定非全0。这样,
,可知,当
时k-b<lowbit(k)-lowbit(b)成立。其他情况下,对
继续应用该结论即可。这样就证明了所有的b不满足条件。
定理2证毕。