1. 程式人生 > >bzoj2683簡單題 cdq分治

bzoj2683簡單題 cdq分治

cell while put discuss ret ons order struct .com

2683: 簡單題

Time Limit: 50 Sec Memory Limit: 128 MB
Submit: 1803 Solved: 731
[Submit][Status][Discuss]

Description

你有一個N*N的棋盤,每個格子內有一個整數,初始時的時候全部為0,現在需要維護兩種操作:

命令

參數限制

內容

1 x y A

1<=x,y<=N,A是正整數

將格子x,y裏的數字加上A

2 x1 y1 x2 y2

1<=x1<= x2<=N

1<=y1<= y2<=N

輸出x1 y1 x2 y2這個矩形內的數字和

3

終止程序

Input

輸入文件第一行一個正整數N。 接下來每行一個操作。

Output

對於每個2操作,輸出一個對應的答案。

Sample Input

4
1 2 3 3
2 1 1 3 3
1 2 2 2
2 2 2 3 4
3

Sample Output

3
5

HINT

1<=N<=500000,操作數不超過200000個,內存限制20M。
對於100%的數據,操作1中的A不超過2000。

cdq分治三維偏序 三維分別是操作序號,橫坐標,縱坐標
把一個詢問拆成4個,就變成了處理二維前綴和問題
對橫坐標排序,操作序號cdq分治,縱坐標用bit處理

 1 #include<bits/stdc++.h>
 2 #define N 200005
 3 using namespace std;
 4 int n,m,t,c[N*3],ans[N];
 5 struct query{
 6     int x,y,v,id,op,bl;
7 bool operator < (const query &b)const{ 8 if(x==b.x&&y==b.y)return id<b.id; 9 return x==b.x?y<b.y:x<b.x; 10 } 11 }q[N<<2],a[N<<2]; 12 13 void add(int x,int y,int v){ 14 if(!x||!y)return; 15 q[++m].x=x;q[m].y=y;q[m].id=m; 16 q[m].op=2;q[m].bl=t;q[m].v=v; 17 } 18 void update(int p,int x){ 19 while(p<=n){ 20 c[p]+=x; 21 p+=p&-p; 22 } 23 } 24 int ask(int x){ 25 int ret=0; 26 while(x){ 27 ret+=c[x]; 28 x-=x&-x; 29 } 30 return ret; 31 } 32 33 void solve(int l,int r){ 34 if(l==r)return; 35 int mid=(l+r)>>1,p1=l,p2=mid+1; 36 for(int i=l;i<=r;++i){ 37 if(q[i].id<=mid&&q[i].op==1)update(q[i].y,q[i].v); 38 if(q[i].id>mid&&q[i].op==2)ans[q[i].bl]+=ask(q[i].y)*q[i].v; 39 } 40 for(int i=l;i<=r;++i) 41 if(q[i].op==1&&q[i].id<=mid)update(q[i].y,-q[i].v); 42 for(int i=l;i<=r;++i){ 43 if(q[i].id<=mid)a[p1++]=q[i]; 44 else a[p2++]=q[i]; 45 } 46 for(int i=l;i<=r;++i)q[i]=a[i]; 47 solve(l,mid);solve(mid+1,r); 48 } 49 int main(){ 50 scanf("%d",&n); 51 while(1){ 52 static int op,x1,x2,y1,y2,v; 53 scanf("%d",&op); 54 if(op==1){ 55 scanf("%d%d%d",&x1,&y1,&v); 56 q[++m].x=x1;q[m].y=y1;q[m].v=v; 57 q[m].id=m;q[m].op=op; 58 } 59 if(op==2){ 60 scanf("%d%d%d%d",&x1,&y1,&x2,&y2);++t; 61 add(x1-1,y1-1,1);add(x2,y2,1); 62 add(x1-1,y2,-1);add(x2,y1-1,-1); 63 } 64 if(op==3)break; 65 } 66 sort(q+1,q+1+m); 67 solve(1,m); 68 for(int i=1;i<=t;i++) 69 printf("%d\n",ans[i]); 70 return 0; 71 }

bzoj2683簡單題 cdq分治