树状数组正确性的证明、、、

树状数组:
先明确一下:
树状数组维护的数据必须带有可减性,可并性、、、
可减性:如某某的和,可并性:如把[1,l]和[l,r]的区间信息并起来能得到1~r。
Modify:

ADD[x];
for(;x <= n;x += x & -x)t[x] += d;

Query:

[l,r]
int s = 0;
for(l --;l;l -= l & -l)s -= t[l];
for(;r;r -= r & -r)s += t[r];
return s;

这里是区间求和、、、
关于树状数组正确性的证明:
首先明确一点:
树状数组在加了p次之后,会变为2^k的形式、、、
那么我们就知道,位置为2^k的点内的信息涵盖了1~2^k所有信息,且不重复、、、
那么我们也可以知道,2^i ~ 2^j的点我们用两次Query相减即可、、、
我们考虑询问:
[l,2^k]或者[2^k,r],我们发现,根据它的可减性,2^k只要减掉1~l - 1之间的所有东西即可证明是正确的。
我们假设l在第j次l -= l & -l的时候,l = 2 ^ p。
实际上只要证明:t[l - 1]涵盖了2^p ~ l - 1的所有信息即可。
我们接下来开始『草率地』证明、、、
l –;
lp = l;
l ^= (2^p);
则:区间变为:[2^p + 1 ~ 2^p + l];
我们来考虑一下,存储2 ^ p + 1的值,就会在t[2 ^ p + 2]上加上2 ^ p + 1的值,而存储2 ^ p +2的值时,就会在t[2 ^ p + 4]上加上这个值,存储2 ^ p + 3的值时,会在t[2 ^ p +4]上加上这个值、、、
这是很显然的、、、
那么我们可以把它的区间缩小了,对不对?
刚刚显然的结论能够至少把区间缩小到[2 ^ p + 4] ……
没错我是来卖萌的,实际上能把区间完全覆盖、、、
我们找到一个恰好再次小于l的2^q,那么在t[2 ^ p + 2^q]这段区间上,显然都已经存储了之前所有的信息……,l -= 2 ^ q,而根据之前的结论,我们可以再次逼近l、、、
所以我们发现其实树状数组的区间就是完美覆盖掉的……
实际上就是二进制数的应用、、、
我们找到一个l:
10010101011
-10000000000
变为:
10101011
->101011
->1011
->11
->1
->0。
没兴趣写了……我们能无限缩小二进制数到一个点,所以树状数组是正确的……『好草率啊』

你可能感兴趣的:(树状数组正确性的证明、、、)