1. 程式人生 > >bzoj 2683: 簡單題

bzoj 2683: 簡單題

接下來 space 簡單 enter class 類型 輸入 online color

2683: 簡單題

Time Limit: 50 Sec Memory Limit: 128 MB
Submit: 1779 Solved: 720
[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分治。
    用CDQ分治做了線段樹練習之後感覺大體脈絡了解了一點,再做這個題,發現基本思路是一樣的,就是會出現其他算法的插入,比如說加一點數據結構維護多維什麽的。
    這個題用了樹狀數組,註意樹狀數組的插入和詢問是在哪個位置使用的
*/
#include<iostream>
#include<cstdio>
#include<algorithm>
#define
maxn 800010 using namespace std; int n,tot,T,ans[maxn],tr[maxn]; struct node{ int t;//第幾次操作 int x,y;//操作的位置 int z;//增加量 int belong;//屬於哪次查詢 int op;//操作類型 bool operator < (const node & q1)const{ if(x!=q1.x)return x<q1.x; if(y!=q1.y)return y<q1.y; return op<q1.op; } }q[maxn],tmp[maxn]; void modify(int x,int v){ while(x<=n){ tr[x]+=v; x+=x&(-x); } } int query(int x){ int sum=0; while(x){ sum+=tr[x]; x-=x&(-x); } return sum; } void work(int l,int r){ if(l==r)return; int mid=(l+r)>>1; for(int i=l;i<=r;i++){ if(q[i].t<=mid&&q[i].op==1)modify(q[i].y,q[i].z); if(q[i].t>mid&&q[i].op==2) ans[q[i].belong]+=query(q[i].y)*q[i].z; } for(int i=l;i<=r;i++) if(q[i].t<=mid&&q[i].op==1)modify(q[i].y,-q[i].z);//進行恢復操作 int l1=l,l2=mid+1; for(int i=l;i<=r;i++){ if(q[i].t<=mid)tmp[l1++]=q[i]; else tmp[l2++]=q[i]; } for(int i=l;i<=r;i++)q[i]=tmp[i]; work(l,mid);work(mid+1,r); } int main(){ freopen("Cola.txt","r",stdin); scanf("%d",&n); int opt,x1,y1,x2,y2,x,y,z; while(1){ scanf("%d",&opt); if(opt==3)break; if(opt==1){ scanf("%d%d%d",&x,&y,&z); q[++tot].x=x;q[tot].y=y;q[tot].t=tot;q[tot].op=1;q[tot].z=z; } if(opt==2){ scanf("%d%d%d%d",&x1,&y1,&x2,&y2); q[++tot].x=x1-1;q[tot].y=y1-1;q[tot].t=tot;q[tot].op=2;q[tot].z=1;q[tot].belong=++T; q[++tot].x=x1-1;q[tot].y=y2;q[tot].t=tot;q[tot].op=2;q[tot].z=-1;q[tot].belong=T; q[++tot].x=x2;q[tot].y=y1-1;q[tot].t=tot;q[tot].op=2;q[tot].z=-1;q[tot].belong=T; q[++tot].x=x2;q[tot].y=y2;q[tot].t=tot;q[tot].op=2;q[tot].z=1;q[tot].belong=T; } } sort(q+1,q+tot+1); work(1,tot); for(int i=1;i<=T;i++)printf("%d\n",ans[i]); return 0; }

bzoj 2683: 簡單題