[Vijos] SuperBrother打鼹鼠
背景
SuperBrother在机房里闲着没事干(再对比一下他的NOIP,真是讽刺啊......),于是便无聊地开始玩“打鼹鼠”......
描述
在这个“打鼹鼠”的游戏中,鼹鼠会不时地从洞中钻出来,不过不会从洞口钻进去(鼹鼠真胆大……)。洞口都在一个大小为n(n<=1024)的正方形中。这个正方形在一个平面直角坐标系中,左下角为(0,0),右上角为(n-1,n-1)。洞口所在的位置都是整点,就是横纵坐标都为整数的点。而SuperBrother也不时地会想知道某一个范围的鼹鼠总数。这就是你的任务。
格式
输入格式
每个输入文件有多行。
第一行,一个数n,表示鼹鼠的范围。
以后每一行开头都有一个数m,表示不同的操作:
m=1,那么后面跟着3个数x,y,k(0<=x,y<n),表示在点(x,y)处新出现了k只鼹鼠;
m=2,那么后面跟着4个数x1,y1,x2,y2(0<=x1<=x2<n,0<=y1<=y2<n),表示询问矩形(x1,y1)-(x2,y2)内的鼹鼠数量;
m=3,表示老师来了,不能玩了。保证这个数会在输入的最后一行。
询问数不会超过10000,鼹鼠数不会超过maxlongint。
输出格式
对于每个m=2,输出一行数,这行数只有一个数,即所询问的区域内鼹鼠的个数。
样例1
样例输入1
4
1 2 2 5
2 0 0 2 3
3
样例输出1
5
限制
各个测试点1s
提示
水题一道。
所有数据均为随机生成,包括样例……
来源
gnaggnoyil
思路
线段树套线段树维护二维区间和即可;
代码实现
1 #include<cstdio> 2 #define LL long long 3 const int maxm=4e3+120; 4 inline LL min_(LL x,LL y){return x<y?x:y;} 5 inline LL max_(LL x,LL y){return x>y?x:y;} 6 int n,m; 7 LL t[maxm][maxm]; 8 void y_add(int k,int l,int r,int x,int y,int p){ 9 if(l==r){ 10 t[y][k]+=p; 11 return; 12 } 13 int mid=l+r>>1,ls=k<<1,rs=ls|1; 14 if(x<=mid) y_add(ls,l,mid,x,y,p); 15 else y_add(rs,mid+1,r,x,y,p); 16 t[y][k]=t[y][ls]+t[y][rs]; 17 } 18 void x_add(int k,int l,int r,int x,int y,int p){ 19 if(l==r){ 20 y_add(1,0,n,y,k,p); 21 return; 22 } 23 int mid=l+r>>1,ls=k<<1,rs=ls|1; 24 if(x<=mid) x_add(ls,l,mid,x,y,p); 25 else x_add(rs,mid+1,r,x,y,p); 26 y_add(1,0,n,y,k,p); 27 } 28 LL y_tot(int k,int l,int r,int al,int ar,int p){ 29 if(l==al&&r==ar) return t[p][k]; 30 LL ret=0; 31 int mid=l+r>>1,ls=k<<1,rs=ls|1; 32 if(al<=mid) ret+=y_tot(ls,l,mid,al,min_(ar,mid),p); 33 if(ar>mid) ret+=y_tot(rs,mid+1,r,max_(al,mid+1),ar,p); 34 return ret; 35 } 36 LL x_tot(int k,int l,int r,int al,int ar,int x,int y){ 37 if(l==al&&r==ar) return y_tot(1,0,n,x,y,k); 38 LL ret=0; 39 int mid=l+r>>1,ls=k<<1,rs=ls|1; 40 if(al<=mid) ret+=x_tot(ls,l,mid,al,min_(ar,mid),x,y); 41 if(ar>mid) ret+=x_tot(rs,mid+1,r,max_(al,mid+1),ar,x,y); 42 return ret; 43 } 44 int main(){ 45 scanf("%d",&n); 46 int x1,x2,y1,y2,x,y,k; 47 while(scanf("%d",&m),m!=3){ 48 if(m==1){ 49 scanf("%d%d%d",&x,&y,&k); 50 x_add(1,0,n,x,y,k); 51 } 52 else{ 53 scanf("%d%d%d%d",&x1,&y1,&x2,&y2); 54 printf("%lld\n",x_tot(1,0,n,x1,x2,y1,y2)); 55 } 56 } 57 return 0; 58 }
这随手写出来的一坨,好像是我平生第一棵树套树QUQ
肚子有点饿,手开始冷了的说。。。