数据结构----树状数组----二维区间的修改与查询
2017-03-15 13:50
357 查看
一、二维树状数组(如果不知道树状数组,请点这里)
先来看一下一维的树状数组的结构:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201703/15/509b32a8d2a4630e5067d031fe415c44)
其实二维树状数组也差不多,只不过每一行和每一列都是一个树状数组,画出来就有些眼花缭乱了,在这里就不画出来了,先把getsum()和update()的代码写出来吧。
getsum():
int lowbit(int x)
{
return x&-x;
}
int getsum2(int x,int y)
{
int sum=0,i,j;
for(i=x;i>0;i-=lowbit(i)){
for(j=y;j>0;j-=lowbit(j)){
sum+=treearray[i][j];
}
}
return sum;
}update():
void update2(int x,int y,int d)
{
for(int i=x;i<=N;i+=lowbit(i)){
for(int j=y;j<=N;j+=lowbit(j)){
treearray[i][j]+=d;
}
}
}可以看出二维树状数组和一维树状数组在代码之间是比较相似的。
来看一道例题:
二、题目描述
[align=left]写一个程序,能够接收这些基站的报告,并回答关于指定矩形区域内的活动移动电话数量的询问。[/align]
[align=left]由若干行组成,每行由一个指令字(整数)和一些整数参数组成。指令字含义为:[/align]
[align=left]指令参数意义[/align]
[align=left]0 S 初始化S*S 的区域为全0,该指令仅在开头出现一次。(1<=S<=1500)[/align]
[align=left]1 X Y A 在方块(X,Y)处加上A个活动移动电话,A可为正可为负。[/align]
[align=left]2 L B R T 询问各个方块中活动移动电话的数量之和,L ≤ X ≤ R, B ≤ Y ≤ T[/align]
[align=left]3 结束程序,该指令仅在结束时出现一次。[/align]
保证数据在给定范围内,不必检验。如果A是负数, 可以保证不会使某个方块的值减小为负数。下标从0开始,也就是说,对于 4×4 的区域, 有 0
≤ X ≤ 3 , 0 ≤ Y ≤ 3。
对每一个指令字为2的输入,在一行上回答一个询问
这道题其实就是一个二维树状数组的应用,很简单,直接上代码:
#include<cstdio>
#include<cstring>
int treearray[1502][1502],N;
int lowbit(int x)
{
return x&-x;
}
int getsum2(int x,int y)
{
int sum=0,i,j;
for(i=x;i>0;i-=lowbit(i)){
for(j=y;j>0;j-=lowbit(j)){
sum+=treearray[i][j];
}
}
return sum;
}
void update2(int x,int y,int d)
{
for(int i=x;i<=N;i+=lowbit(i)){
for(int j=y;j<=N;j+=lowbit(j)){
treearray[i][j]+=d;
}
}
}
int main()
{
int o,x,y,z,w,d;
while(1){
scanf("%d",&o);
if(o==0) scanf("%d",&N);
else if(o==3) break;
else if(o==1){scanf("%d%d%d",&x,&y,&d);update2(x+1,y+1,d);}
else if(o==2){scanf("%d%d%d%d",&x,&y,&z,&w);printf("%d\n",getsum2(z+1,w+1)-getsum2(x,w+1)-getsum2(z+1,y)+getsum2(x,y));}
}
}
先来看一下一维的树状数组的结构:
其实二维树状数组也差不多,只不过每一行和每一列都是一个树状数组,画出来就有些眼花缭乱了,在这里就不画出来了,先把getsum()和update()的代码写出来吧。
getsum():
int lowbit(int x)
{
return x&-x;
}
int getsum2(int x,int y)
{
int sum=0,i,j;
for(i=x;i>0;i-=lowbit(i)){
for(j=y;j>0;j-=lowbit(j)){
sum+=treearray[i][j];
}
}
return sum;
}update():
void update2(int x,int y,int d)
{
for(int i=x;i<=N;i+=lowbit(i)){
for(int j=y;j<=N;j+=lowbit(j)){
treearray[i][j]+=d;
}
}
}可以看出二维树状数组和一维树状数组在代码之间是比较相似的。
来看一道例题:
二、题目描述
二维区间的和
[align=left]假定在Tampere地区的第四代移动电话基站这样运行:整个地区分成方块,方块形成S×S的矩阵,行和列编号从0到S-1.每个方块包含一个基站。在每个方块中的活动移动电话数可以改变,因为电话能从一个方块移动到另一个方块,或者电话能开机或关机。每过一段时间,每个基站都向主站报告自身活动电话的改变情况,以及自己在矩阵中的行列位置。[/align][align=left]写一个程序,能够接收这些基站的报告,并回答关于指定矩形区域内的活动移动电话数量的询问。[/align]
输入
[align=left]由若干行组成,每行由一个指令字(整数)和一些整数参数组成。指令字含义为:[/align][align=left]指令参数意义[/align]
[align=left]0 S 初始化S*S 的区域为全0,该指令仅在开头出现一次。(1<=S<=1500)[/align]
[align=left]1 X Y A 在方块(X,Y)处加上A个活动移动电话,A可为正可为负。[/align]
[align=left]2 L B R T 询问各个方块中活动移动电话的数量之和,L ≤ X ≤ R, B ≤ Y ≤ T[/align]
[align=left]3 结束程序,该指令仅在结束时出现一次。[/align]
保证数据在给定范围内,不必检验。如果A是负数, 可以保证不会使某个方块的值减小为负数。下标从0开始,也就是说,对于 4×4 的区域, 有 0
≤ X ≤ 3 , 0 ≤ Y ≤ 3。
输出
对每一个指令字为2的输入,在一行上回答一个询问
样例输入
0 4 1 1 2 3 2 0 0 2 2 1 1 1 2 1 1 2 -1 2 1 1 2 3 3
样例输出
3 4
#include<cstdio>
#include<cstring>
int treearray[1502][1502],N;
int lowbit(int x)
{
return x&-x;
}
int getsum2(int x,int y)
{
int sum=0,i,j;
for(i=x;i>0;i-=lowbit(i)){
for(j=y;j>0;j-=lowbit(j)){
sum+=treearray[i][j];
}
}
return sum;
}
void update2(int x,int y,int d)
{
for(int i=x;i<=N;i+=lowbit(i)){
for(int j=y;j<=N;j+=lowbit(j)){
treearray[i][j]+=d;
}
}
}
int main()
{
int o,x,y,z,w,d;
while(1){
scanf("%d",&o);
if(o==0) scanf("%d",&N);
else if(o==3) break;
else if(o==1){scanf("%d%d%d",&x,&y,&d);update2(x+1,y+1,d);}
else if(o==2){scanf("%d%d%d%d",&x,&y,&z,&w);printf("%d\n",getsum2(z+1,w+1)-getsum2(x,w+1)-getsum2(z+1,y)+getsum2(x,y));}
}
}
相关文章推荐
- POJ 1195 Mobile phones(二维树状数组,点修改,区间查询)
- tyvj P1716 - 上帝造题的七分钟 二维树状数组区间查询及修改 二维线段树
- bzoj 3132 上帝造题的七分钟(二维树状数组区间修改区间查询模板)
- 【bzoj5173】[Jsoi2014]矩形并 扫描线+二维树状数组区间修改区间查询
- 高级树状数组——区间修改区间查询、二维树状数组
- POJ 1195 Mobile phones(二维树状数组,点修改,区间查询)
- 【原创】【数据结构】一维树状数组的基本操作(单点修改,区间查询) (HDU1166 敌兵布阵)
- POJ2155【二维树状数组,区间修改,点查询?】【又被输入输出坑】
- [TYVJ P1716/BZOJ 3132 上帝造题的七分钟] 二维树状数组区间修改、区间查询
- POJ2155【二维树状数组,区间修改,点查询?】【又被输入输出坑】
- POJ 2155-Matrix(二维树状数组-区间修改 单点查询)
- Matrix 二维树状数组 区间修改+单点查询
- POJ2155 Matrix(二维树状数组||区间修改单点查询)
- 【bzoj3132】上帝造题的七分钟 二维树状数组区间修改区间查询
- 二维树状数组(区间修改,单点查询)
- 树状数组的区间修改,单点查询
- hdu 2642二维树状数组 单点更新区间查询 模板题
- POJ 1195 - Mobile phones 二维树状数组(单点更新..区间查询)
- HDU 1556(树状数组-区间修改,查询点)
- HDU 4031 Attack(树状数组修改区间查询点)