BZOJ2683 简单题

 题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2683

题目大意:二维平面上,单点修改权值,区间询问权值和。

CDQ分治裸题。

话说我今天才学CDQ分治,还想了好久才会写的。

将询问拆成4个操作,CDQ分治搞一搞就好了。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #define inf 1<<30
 6 #define maxn 500005
 7 #define maxm 800005
 8 using namespace std;
 9 int n,tot,m,cnt,pos[maxm],t[maxn],ans[maxm];
10 struct fuck{int x,y,op,id,v;}e[maxm];
11 bool comp(fuck a,fuck b){
12     if(a.x==b.x) return a.y<b.y;
13     return a.x<b.x;
14 }
15 void change(int x,int y){for(int i=x;i<=m;i+=i&-i) t[i]+=y;}
16 int query(int x){int y=0; for(int i=x;i;i-=i&-i) y+=t[i]; return y;}
17 void solve(int l,int r){
18     if(l==r) return;
19     int mid=(l+r)/2;
20     solve(l,mid); solve(mid+1,r);
21     sort(e+l,e+mid+1,comp); sort(e+mid+1,e+r+1,comp);
22     int i=l,j=mid+1,last=0;
23     while(j<=r){
24         while(i<=mid&&e[i].op==2) i++;
25         while(j<=r&&e[j].op==1) j++;
26         if(i<=mid&&e[i].x<=e[j].x) change(e[i].y,e[i].v),last=i++;
27         else if(j<=r) ans[e[j].id]+=query(e[j].y),++j;
28     }
29     for(int i=l;i<=last;i++) if(e[i].op==1) change(e[i].y,-e[i].v);
30 }
31 int main(){
32     scanf("%d",&n);
33     int type,x1,x2,y1,y2;
34     while(1){
35         scanf("%d",&type);
36         if(type==1){e[++m].op=1; e[m].id=m; scanf("%d%d%d",&e[m].x,&e[m].y,&e[m].v);}
37         else if(type==2){
38             pos[++cnt]=m;
39             scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
40             e[++m].op=2; e[m].x=x2; e[m].y=y2; e[m].id=m;
41             e[++m].op=2; e[m].x=x1-1; e[m].y=y1-1; e[m].id=m;
42             e[++m].op=2; e[m].x=x2; e[m].y=y1-1; e[m].id=m;
43             e[++m].op=2; e[m].x=x1-1; e[m].y=y2; e[m].id=m;
44         }
45         else break;
46     }
47     solve(1,m);
48     for(int i=1;i<=cnt;i++) printf("%d\n",ans[pos[i]+1]+ans[pos[i]+2]-ans[pos[i]+3]-ans[pos[i]+4]);
49     return 0;
50 }
View Code

 

posted @ 2016-05-18 19:59  I'mLS  阅读(303)  评论(3编辑  收藏  举报