关于线段树与树状数组的关键思想
单点更新,区间求和
线段树:
对单点,肯定要搜到叶子结点,然后回溯整条路径加上VAL
对区间:只要搜到搜索区间在询问区间之内就累加即可
(每个累加的结点分别控制搜索区间的一部分)
树状数组:
对单点:从该位起不断往上增,二进制位包括该位的都累加
对区间:对第N位往下累加可得1~N位的和,求区间就询问右界减询问(左界-1)
(以第1位为标准,全部位都是相对他的差值,所左右界询问值差分即可)
区间更新,单点求和
线段树:
对区间:搜到搜索区间在询问区间之内就停止往下,结点加VAL表示区间所有位加VAL
对单点:从根开始搜到叶节子,路径上所有结点的值全部累加即可
(以根为初始标准,每个结点都是相比其老豆的差值,一直差分到叶节点)
树状数组:
对区间:从左界往上更新1,从(右界+1)往上更新-1,二进制位包括该位的都累加
对单点:对第N位往下累加即得第N位的值,其实就是求前缀和
(以最后的位N为基础,每位I的值表示从I到N增加的值,也是与i-1位的差值)
(比如1,0,-1,0,求第二位的值扫0,1累加是1,因为第一位1表示1-N位全+1)
区间更新,区间求和
线段树:
对更新:搜到搜索区间在询问区间之内就停止往下,结点VAL表示区间所有位都加VAL
然后开个LAZY数组表示还需要往下更新的值
对求和:只要搜到搜索区间在询问区间之内就累加即可,但每次搜索时同时下推LAZY
数状数组:(不建议)
对更新:开两个树状数组维护一次和与阶梯和
对求和:设X是范围,i是当前查询的位置,查询1~i位 的和
sum(sum(C[j],j<=i)i<=x)= x*C[1]+(x-1)*C[2]+……+C[x] =(x+1)*sum(C[i],i<=x)-sum(i*C[i],i<=x)
其中(x+1)是定值,所以要求1~i位的一次和S1与阶梯和S2,然后(x+1)*S1-S2就是结果