二维树状数组可以实现在平面上的区域加、区域查询等操作。
区域修改
我们在一维时维护树状数组的区间操作时,对其进行了差分。类比一维的思想,我们在二维平面上也对树状数组差分。
我们来看二维的前缀和:
\[sum(i,j)=sum(i-1,j)+sum(i,j-1)-sum(i-1,j-1)+a(i,j) \]可以使二维差分数组为这样的形式:
\[d(i,j)=a(i,j)-d(i-1,j)-d(i,j-1)+d(i-1,j-1) \](发现了吧,这其实就是)
比如我们有一下这个全为 \(0\) 的矩阵,那么给中间 \(2\times 3\) 的矩阵差分后长成这样:(“o” 表示操作区域)
0 0 0 0 0 +x 0 0 -x 0
0 o o o 0 -> 0 0 0 0 0
0 o o o 0 -x 0 0 +x 0
0 0 0 0 0 0 0 0 0 0
这样我们就简单地完成了区域加的操作。
区域查询
根据差分数组的定义,我们不难发现,对于点 \((x,y)\) ,它的二维前缀和就是:
\[\sum_{i=1}^x\sum_{j=1}^y\sum_{h=1}^i\sum_{k=1}^j d[h][k] \]但我们类比一下一维树状数组的区间求和,我们亦可以统计每个 \(d[h][k]\) 出现的次数,我们就可以发现 \(d[1][1]\) 出现了 \((x\times y)\) 次,\(d[1][2]\) 出现了 \(x\times(y-1)\) 次……\(d[h][k]\) 出现了 \((x-h+1)\times (y-k+1)\) 次。
则原式整理得:
\[\sum_{i=1}^x\sum_{j=1}^y d[i][j]\times (x-i+1)\times (y-j+1) \]分解得:
\[\sum_{i=1}^x\sum_{j=1}^y d[i][j]\times [(xy-xj+x)+(-yi+ij-i)+(y-j+1)] \]最后得:
\[\sum_{i=1}^x\sum_{j=1}^y d[i][j]\times (xy+x+y+1)-d[i][j]\times i(y+1)-d[i][j]\times j(x+1)+d[i][j]\times i\times j \]根据我们最后分解出来的公式,我们需要维护四个数组 \(d[i][j],d[i][j]\times i,d[i][j]\times j,d[i][j]\times i\times j\) ,从而实现区间查询。
例题 — P4514 上帝造题的七分钟
即二维树状数组裸题。
$\texttt{code}$
咕咕咕
标签:树状,sum,差分,times,二维,数组 来源: https://www.cnblogs.com/EricQian/p/15375842.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。