树状数组使用总结

Posted guessycb

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了树状数组使用总结相关的知识,希望对你有一定的参考价值。

树状数组使用总结

在考试中 因为不清楚二维树状数组怎么用 而失手了无数遍了...
今天终于把这个坑填了.... =_=

1.区间修改+单点查询(一维)

把查询第\\(x\\)个位置的值\\(s_x\\)变为查询前缀和\\(s_x = \\sum_{i = 1}^x d(i)\\)
其中 \\(d(x) = s_x - s_{x-1}\\)
修改\\([L,R]\\)的时侯,只需要修改 \\(L\\)\\(R\\)+\\(1\\) 两个点。

2.区间修改+区间查询(一维)

查询\\([1,x]\\),则有:
\\[res = \\sum_{i=1}^x s_x = \\sum_{i = 1}^x \\sum_{j = 1}^i d(j)\\]
\\[\\sum_{i = 1}^x \\sum_{j = 1}^i d(j) = \\sum_{j = 1}^x d(j)(x - j + 1) = (x+1)\\sum_{j = 1}^x d(j) - \\sum_{j = 1}^x d(j)j\\]
所以用两个树状数组分别维护\\(\\sum d(i)\\)\\(\\sum d(i)*i\\)即可。

3.单点修改+区间查询(二维)

直接维护\\((1,1)\\)\\((x,y)\\)的这个矩阵的和即可。 代码类似一维处理即可:

for( x ; x <= n ; x += lowbit(x) )
\\(\\ \\ \\ \\ \\ \\)for( y ; y <= m ; y += lowbit(y) )
\\(\\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\)updata or query

查询时用一下二维前缀和容斥一下就行了。

4.区间修改+单点查询(二维)

一样的转为差分值:\\(s_{\\{x,y\\}} = \\sum_{i = 1}^x \\sum_{j=1}^y d(i,j)\\)
其中$d(i,j) = s_{{x,y}} - s_{{x-1,y}} - s_{{x,y-1}} + s_{{x-1,y-1}} $
修改时只修改\\((x_1,y_1)\\)\\((x_1,y_2+1)\\)\\((x_2+1,y_1)\\)\\((x_2+1,y_2+1)\\)
查询时一样的用 单点修改+区间查询(二维) 的方法查询。

5.区间修改+区间查询(二维)

\\[res = \\sum_{i=1}^x \\sum_{j=1}^y \\sum_{k=1}^i \\sum_{h=1}^j d(k,h)\\]
把后面两个\\(\\sum\\)提到前面来:
\\[res = \\sum_{i=1}^x \\sum_{j=1}^y d(i,j)(x-i+1)(y-j+1)\\]
展开后得到:
$res = res $

$+(x+1)(y+1)*?[?\\sum_{i=1}^x \\sum_{j=1}^y d(i,j)?] $
\\(- (x+1)*\\ [\\ \\sum_{i=1}^x \\sum_{j=1}^y d(i,j)j\\ ]\\)
\\(- (y+1)*\\ [\\ \\sum_{i=1}^x \\sum_{j=1}^y d(i,j)i\\ ]\\)
\\(+ [\\ \\sum_{i=1}^x \\sum_{j=1}^y d(i,j)ij\\ ]\\)
所以用四个树状数组分别维护\\(\\sum d()\\) , \\(\\sum d()i\\) , \\(\\sum d()j\\) , \\(\\sum d()ij\\) 即可 , 具体实现戳这里

以上是关于树状数组使用总结的主要内容,如果未能解决你的问题,请参考以下文章

树状数组总结篇

树状数组小结

树状数组总结

浅谈树状数组

树状数组的知识总结

浅析树状数组