0
点赞
收藏
分享

微信扫一扫

POJ--1195(二维树状数组单点修改+区间查询板子题)

飞鸟不急 2022-09-26 阅读 127

地址:​​http://poj.org/problem?id=1195​​

题意:

0 s: s*s的初始为0的矩阵a[][]

1 X Y A:a[x][y]+A

2 L B R T:左上角a[L][B]到右下角a[R][T]的矩阵和。

解析:

二维数组数组板子,和一维基本类似:

void update(int x,int y,int z)
{
// cout<<"?";
for(int i=x;i<=n;i+=lowbit(i))
for(int j=y;j<=n;j+=lowbit(j))
c[i][j]+=z;
}
int getsum(int x,int y)
{
int sum = 0 ;
for(int i=x;i>=1;i-=lowbit(i))
for(int j=y;j>=1;j-=lowbit(j))
sum+=c[i][j];
return sum;
}

求和,画图即可理解,左上角被减去了两次。

坐标都要记得+1,因为树状数组i=0时无效

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=1200;
int c[maxn][maxn];
int x,n;
int lowbit(int x)
{
return x&(-x);
}
void update(int x,int y,int z)
{
// cout<<"?";
for(int i=x;i<=n;i+=lowbit(i))
for(int j=y;j<=n;j+=lowbit(j))
c[i][j]+=z;
}
int getsum(int x,int y)
{
int sum = 0 ;
for(int i=x;i>=1;i-=lowbit(i))
for(int j=y;j>=1;j-=lowbit(j))
sum+=c[i][j];
return sum;
}
int getall(int x1,int y1,int x2,int y2)
{
return getsum(x2,y2)-getsum(x1-1,y2)-getsum(x2,y1-1)+getsum(x1-1,y1-1);
}
int main()
{
while(scanf("%d",&x)!=EOF)
{
if(x==0)
{
scanf("%d",&n);
memset(c,0,sizeof(c));
}
else if(x==1)
{
int i,j,y;
scanf("%d%d%d",&i,&j,&y);
update(i+1,j+1,y);
}
else if(x==2)
{
int x1,y1,x2,y2;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
cout<<getall(x1+1,y1+1,x2+1,y2+1)<<endl;
}
}
}

 



举报

相关推荐

0 条评论