Problem
题意:给定二维平面,维护单点加与区间求和操作
Solution
蒟蒻最近开始学数据结构了,发现了二维结构这种神奇的东东
这题不过就是二维树状数组或线段树的裸题,发这篇博客不过是为了贴个板子
Code
二维树状数组
#include<cstdio>
#include<cstring>
using namespace std;
#define lowbit(x) (-x&x)
const int maxn=1050;
int n,f[maxn][maxn];
inline void add(int x,int y,int add){
for(int i=x;i<=n;i+=lowbit(i))for(int j=y;j<=n;j+=lowbit(j))f[i][j]+=add;
return ;
}
inline int query(int x,int y){
int sum=0;
for(int i=x;i;i-=lowbit(i))for(int j=y;j;j-=lowbit(j))sum+=f[i][j];
return sum;
}
int main(){
int p;
int a,b,c;
int l,xia,r,shang;
while(1){
scanf("%d",&p);
if(!p){scanf("%d",&n);memset(f,0,sizeof(f));continue;}
else if(p==1){scanf("%d%d%d",&a,&b,&c);add(a+1,b+1,c);continue;}
else if(p==2){scanf("%d%d%d%d",&l,&xia,&r,&shang);l++,r++,xia++,shang++;printf("%d\n",query(r,shang)+query(l-1,xia-1)-query(l-1,shang)-query(r,xia-1));continue;}
else if(p==3)return 0;
}
return 0;
}
二维线段树
#include<cstdio>
#include<cctype>
using namespace std;
typedef long long ll;
#define rg register
#define cl(x) memset(x,0,sizeof(x))
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
#define abs(x) ((x)>0?(x):(-(x)))
template <typename _Tp> inline _Tp read(_Tp&x){
rg char c11=getchar(),ob=0;x=0;
while(c11^'-'&&!isdigit(c11))c11=getchar();if(c11=='-')c11=getchar(),ob=1;
while(isdigit(c11))x=x*10+c11-'0',c11=getchar();if(ob)x=-x;return x;
}
const int N=1010;
int seg[N<<2][N<<2],n;
#define mid (((l)+(r))>>1)
inline void add2(int x,int l,int r,int xx,int Y,int Z){
seg[x][xx]+=Z;
if(l==r)return ;
if(Y<=mid)add2(x,l,mid,xx<<1,Y,Z);
else add2(x,mid+1,r,xx<<1|1,Y,Z);
return ;
}
inline void add1(int l,int r,int x,int X,int Y,int Z){
add2(x,1,n,1,Y,Z);
if(l==r)return ;
if(X<=mid)add1(l,mid,x<<1,X,Y,Z);
else add1(mid+1,r,x<<1|1,X,Y,Z);
return ;
}
inline int sum2(int x,int l,int r,int xx,int B,int T){
if(B<=l&&r<=T)return seg[x][xx];
int tmp(0);
if(B<=mid)tmp+=sum2(x,l,mid,xx<<1,B,T);
if(mid<T)tmp+=sum2(x,mid+1,r,xx<<1|1,B,T);
return tmp;
}
inline int sum1(int l,int r,int x,int L,int R,int B,int T){
if(L<=l&&r<=R)return sum2(x,1,n,1,B,T);
int tmp(0);
if(L<=mid)tmp+=sum1(l,mid,x<<1,L,R,B,T);
if(mid<R)tmp+=sum1(mid+1,r,x<<1|1,L,R,B,T);
return tmp;
}
int main(){
int opt,x,y,z,l,r,b,t;
while(1){
read(opt);
switch(opt){
case 0:read(n);break;
case 1:read(x),read(y),read(z);add1(1,n,1,x+1,y+1,z);break;
case 2:read(l),read(b),read(r),read(t);printf("%d\n",sum1(1,n,1,l+1,r+1,b+1,t+1));break;
case 3:return 0;
default : puts("ERROR"); return 0;
}
}
return 0;
}