导
树状数组相信大家都很熟悉了,而今天我将会为大家带了一些更加全面的操作,并且欢迎补充哦。
其实我想说的是,除了RMQ,线段树能做的,树状数组都能做。
换句话说,这是一个稍微进阶版的的树状数组,读者至少要会单调修改区间查询这个最基本的操作。
树状数组应该算是常数非常小的数据结构啦。而小生特别喜欢这个数据结构,这是因为它特别短,就是又短又快!
核心操作:lowbit
int lowbit(int x)
{
return x&-x;
}
这是树状数组的核心操作,看到了这个操作基本上就是树状数组了。
现在我们来看看这个操作的实际意义:
抛结论:令p=lowbit(x),则p在x在二进制下从右往左第一个1的位置上也为1,其它为0。
举个例子:lowbit( ( 110 )2 ) = (10)2
操作
单点修改区间查询
我觉得这个。。。很简单吧
区间修改单点查询
这里就是利用差分的思想。
令a为原数组
令一个新的数组b:b[1]=a[1],b[i]=b[i]-b[i-1]。(差分数组)
那么a[i]=b[1]+b[2]+….+b[i]
这样我们用树状数组维护差分数组b即可,也就不维护原数组了,每次修改区间的时候只会有两个b被修改,因此可以在log级别完成查找与维护。
此外,由于任何一段b的区间和都可以写成两个a的差,因此一般情况下b的储存类型和a是相同的。
区间修改区间查询
基于区间修改单点查询
我们看看前缀和