[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

肚子有点饿,手开始冷了的说。。。

posted @ 2017-12-15 17:32  J_william  阅读(830)  评论(0编辑  收藏  举报