COGS1752. [BOI2007]摩基亚Mokia CDQ
CDQ的板子题
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define MAXN 2000010 using namespace std; inline int read() { int sum=0; char ch=getchar(); while(ch<'0'||ch>'9')ch=getchar(); while(ch>='0'&&ch<='9') { sum=(sum<<1)+(sum<<3)+ch-'0'; ch=getchar(); } return sum; } int Y[MAXN],W; inline void update(int pos,int p) { while(pos<=W) { Y[pos]+=p; pos+=pos&(-pos); } } inline int get_sum(int pos) { int sum=0; while(pos>0) { sum+=Y[pos]; pos-=pos&(-pos); } return sum; } struct QUERY { int opt,id,x,y,t; }A[200010],temp[200010]; int sz; int Ans[10001]; int comp(const QUERY a,const QUERY b) { return a.x<b.x||(a.x==b.x&&a.opt<b.opt); } void CDQ(int l,int r) { if(l==r)return; int mid=(l+r)>>1; for(int i=l;i<=r;i++) if(A[i].opt) { if(A[i].id>mid) { if(A[i].t>0) Ans[A[i].t]+=get_sum(A[i].y); else Ans[0-A[i].t]-=get_sum(A[i].y); } } else if(A[i].id<=mid) update(A[i].y,A[i].t); for(int i=l;i<=r;i++) if(A[i].opt==0&&A[i].id<=mid) update(A[i].y,-A[i].t); int l1=l,l2=mid+1; for(int i=l;i<=r;i++) if(A[i].id<=mid) temp[l1++]=A[i]; else temp[l2++]=A[i]; for(int i=l;i<=r;i++) A[i]=temp[i]; CDQ(l,mid); CDQ(mid+1,r); } int T; void Init() { W=read(),W=read(); while(1) { int opt=read(); if(opt==1) { A[++sz].opt=0; A[sz].x=read(); A[sz].y=read(); A[sz].id=sz; A[sz].t=read(); continue; } if(opt==2) { T++; int X1=read(),Y1=read(),X2=read(),Y2=read(); A[++sz].opt=1; A[sz].id=sz; A[sz].x=X2; A[sz].y=Y2; A[sz].t=T; if(X1!=1) { A[++sz].opt=1; A[sz].id=sz; A[sz].x=X1-1; A[sz].y=Y2; A[sz].t=-T; } if(Y1!=1) { A[++sz].opt=1; A[sz].id=sz; A[sz].x=X2; A[sz].y=Y1-1; A[sz].t=-T; } if(X1!=1&&Y1!=1) { A[++sz].opt=1; A[sz].id=sz; A[sz].x=X1-1; A[sz].y=Y1-1; A[sz].t=T; } } if(opt==3)break; } sort(A+1,A+sz+1,comp); CDQ(1,sz); } inline void print() { for(int i=1;i<=T;i++) printf("%d\n",Ans[i]); } int main() { freopen("mokia.in","r",stdin); freopen("mokia.out","w",stdout); Init(); print(); return 0; }
苟利国家生死以, 岂因祸福避趋之。