码迷,mamicode.com
首页 > 编程语言 > 详细

树状数组使用总结

时间:2018-02-22 19:29:03      阅读:175      评论:0      收藏:0      [点我收藏+]

标签:log   数组使用   树状   树状数组   展开   矩阵   ...   直接   upd   

树状数组使用总结

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

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\) 即可 , 具体实现戳这里

树状数组使用总结

标签:log   数组使用   树状   树状数组   展开   矩阵   ...   直接   upd   

原文地址:https://www.cnblogs.com/GuessYCB/p/8459584.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!