是一道简单的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 }