1. 程式人生 > >BZOJ2683 簡單題

BZOJ2683 簡單題

一道 div pos main 般的 代碼 () void sca

是一道簡單的CDQ分治,等做夠一些以後會做一個CDQ的專題。

對於時間和x建立確定兩維加上y是三維偏序,學習了一個time標記,如果這次time不同的話就不進行操作,這樣的話可以省去一般的時間。

代碼 By:大奕哥

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

BZOJ2683 簡單題