BOI2007 Mokia 摩基亚
题解:
容斥,将询问变成4个加权询问。
然后就是cdq了。
代码:
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define N 200050 #define ll long long inline int rd() { int f=1,c=0;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){c=10*c+ch-'0';ch=getchar();} return f*c; } int typ,w,tim=1,cnt; struct node { int x,y,t,w,k; node(){} node(int t,int w,int k):t(t),w(w),k(k){} }p[N],tmp[N]; struct xy { int x,id; xy(){} xy(int x,int i):x(x),id(i){} }X[N],Y[N]; bool cmp(xy a,xy b) { return a.x<b.x; } ll ans[N]; struct BIT { ll v[N]; void up(int x,ll d) { if(!x)return ; while(x<N) v[x]+=d,x+=(x&-x); } ll down(int x) { if(!x)return 0; ll ret = 0ll; while(x) ret+=v[x],x-=(x&-x); return ret; } }tr; void Sort(int l,int r) { int mid = (l+r)>>1; int i=l,j=mid+1,k=l; while(i<=mid&&j<=r) { while(i<=mid&&p[i].x<=p[j].x) { tmp[k]=p[i]; i++,k++; } while(j<=r&&p[i].x>p[j].x) { tmp[k]=p[j]; j++,k++; } } while(i<=mid)tmp[k]=p[i],i++,k++; while(j<=r)tmp[k]=p[j],j++,k++; for(i=l;i<=r;i++)p[i]=tmp[i]; } int kkk[N],ct; void cdq(int l,int r) { if(l==r)return ; int mid = (l+r)>>1; cdq(l,mid),cdq(mid+1,r); Sort(l,mid),Sort(mid+1,r); int i,j; for(i=mid+1,j=l;i<=r;i++) { while(j<=mid&&p[j].x<=p[i].x) tr.up(p[j].y,p[j].w),j++; if(p[i].k) ans[kkk[p[i].t]]+=p[i].k*tr.down(p[i].y); } for(j=j-1;j>=l;j--)tr.up(p[j].y,-p[j].w); } int main() { while(scanf("%d",&typ)) { if(typ==0) { w=rd(); }else if(typ==1) { int x=rd(),y=rd(),A=rd(); p[++cnt]=node(tim,A,0);X[cnt]=xy(x,cnt);Y[cnt]=xy(y,cnt); }else if(typ==2) { int lx = rd(),dy = rd(),rx = rd(),uy = rd(); tim++;ct++;kkk[tim]=ct; p[++cnt]=node(tim,0,1);X[cnt]=xy(rx,cnt);Y[cnt]=xy(uy,cnt); p[++cnt]=node(tim,0,1);X[cnt]=xy(lx-1,cnt);Y[cnt]=xy(dy-1,cnt); p[++cnt]=node(tim,0,-1);X[cnt]=xy(lx-1,cnt);Y[cnt]=xy(uy,cnt); p[++cnt]=node(tim,0,-1);X[cnt]=xy(rx,cnt);Y[cnt]=xy(dy-1,cnt); tim++; }else break; } sort(X+1,X+1+cnt,cmp); sort(Y+1,Y+1+cnt,cmp); for(int las=-1,k=0,i=1;i<=cnt;i++) { if(X[i].x!=las) { las = X[i].x; k++; } p[X[i].id].x = k; } for(int las=-1,k=0,i=1;i<=cnt;i++) { if(Y[i].x!=las) { las = Y[i].x; k++; } p[Y[i].id].y = k; } tim--; cdq(1,cnt); for(int i=1;i<=ct;i++) printf("%lld\n",ans[i]); return 0; }