ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【学习笔记】二维树状数组

2022-01-13 20:02:52  阅读:142  来源: 互联网

标签:一维 limits 树状 int sum 笔记 二维 数组


前置芝士

  • 一维树状数组之区间修改、区间查询

  • 二维差分、二维前缀和

  • 知道位置 i 管辖的范围为 \(i-lowbit(i)+1 \sim i\) ,父亲节点为 \(i+lowbit(i)\)

二维树状数组

单点修改,区间查询

思路

解决方案十分暴力,直接在一维树状数组上再套一维即可。

不必思考这棵树具体长什么样子,如果一定要知道就是在一维树状数组的每个节点内部再套一个树状数组(不一定对,但是确实没用)。

代码

inline int lowbit(int x){
	return x&(-x);
}
inline void change(int x,int y,int k){
	for(int i=x;i<=n;i+=lowbit(i))
		for(int j=y;j<=m;j+=lowbit(j))
			C[i][j]+=k;
	return;
}
inline int query(int x,int y){
	int res=0;
	for(int i=x;i;i-=lowbit(i))
		for(int j=y;j;j-=lowbit(i))
			res+=C[i][j];
	return res;
}

区间修改,单点查询

思路

仍然可以利用一维数组的核心思想——差分,仍然十分暴力,只需要利用二维差分进行修改即可。

代码

inline int lowbit(int x){
	return x&(-x);
}
inline void change(int x,int y,int k){
	for(int i=x;i<=n;i+=lowbit(i))
		for(int j=y;j<=m;j+=lowbit(j))
			C[i][j]+=k;
	return;
}
inline void change_s(int x1,int y1,int x2,int y2,int k){
	change(x1,y1,k);
	change(x1,y2+1,-k);
	change(x2+1,y1,-k);
	change(x2+1,y2+1,k);
	return;
}//(x1,y1)是左上角,另一个是右下角 
inline int query(int x,int y){
	int res=0;
	for(int i=x;i;i-=lowbit(i))
		for(int j=y;j;j-=lowbit(i))
			res+=C[i][j];
	return res;
}

区间修改,区间查询

思路

与一维树状数组相似,我们并不打算放弃区间修改的差分思想,所以只好将区间查询进行整活。

对于查询的区间 \((1,1) \sim (x,y)\) ,易知答案为 \(\sum\limits^x_{i=1}\sum\limits^y_{j=1}{差分数组上的(1,1) \sim (i,j)}\) ,也就是 \(\sum\limits^x_{i=1}\sum\limits^y_{j=1}\sum\limits^i_{k=1}\sum\limits^j_{l=1}C[k][l]\) 。

同样是根据一维树状数组的思路,可以利用可以推算出的每个元素出现的次数

代码

标签:一维,limits,树状,int,sum,笔记,二维,数组
来源: https://www.cnblogs.com/Konjac-Binaries/p/15799433.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有