BZOJ 1176
http://www.lydsy.com/JudgeOnline/problem.php?id=1176
x坐标排序
y坐标树状数组维护
时间cdq分治归并排序
对于矩阵(x1,y1,x2,y2)
记录四个点(x1-1,y1-1),(x1-1,y2),(x2,y1-1),(x2,y2)
维护二维前缀和
#include<cstdio> #include<algorithm> #define FOR(i,s,t) for(register int i=s;i<=t;++i) using std::sort; const int N=2000011,M=4000011; int ans[N]; struct point{ int x,y,t,k,v,pos; friend bool operator<(const point A,const point B){ if(A.x!=B.x)return A.x<B.x; if(A.y!=B.y)return A.y<B.y; if(A.k!=B.k)return A.k<B.k; if(A.pos!=B.pos)return A.pos<B.pos; if(A.v!=B.v)return A.v<B.v; return A.t<B.t; } }a[N],tmp[N]; int s,w,k,tot,x1,y1,x2,y2; namespace BIT{ int tr[M]; inline void add(int pos,int v){ for(;pos<=w;pos+=pos&-pos)tr[pos]+=v; } inline int query(int pos){ int ret=0; for(;pos;pos-=pos&-pos)ret+=tr[pos]; return ret; } } using namespace BIT; inline void cdq(int l,int r){ if(l==r)return; int mid=(l+r)>>1,l1=l,l2=mid+1; FOR(i,l,r){ if(a[i].t<=mid&&a[i].k==1)add(a[i].y,a[i].v); if(a[i].t>mid&&a[i].k==2)ans[a[i].pos]+=a[i].v*query(a[i].y); } FOR(i,l,r)if(a[i].t<=mid&&a[i].k==1)add(a[i].y,-a[i].v); FOR(i,l,r)tmp[a[i].t<=mid?l1++:l2++]=a[i]; FOR(i,l,r)a[i]=tmp[i]; cdq(l,mid);cdq(mid+1,r); } int main(){ scanf("%d%d",&s,&w); while(1){ scanf("%d",&k); if(k==3)break; if(k==1){ ++tot; scanf("%d%d%d",&a[tot].x,&a[tot].y,&a[tot].v); a[tot].t=tot;a[tot].k=k; } if(k==2){ scanf("%d%d%d%d",&x1,&y1,&x2,&y2); --x1,--y1; ans[++ans[0]]=(x2-x1)*(y2-y1)*s; a[++tot].x=x2,a[tot].y=y2;a[tot].v=1;a[tot].t=tot;a[tot].k=k;a[tot].pos=ans[0]; a[++tot].x=x1,a[tot].y=y1;a[tot].v=1;a[tot].t=tot;a[tot].k=k;a[tot].pos=ans[0]; a[++tot].x=x1,a[tot].y=y2;a[tot].v=-1;a[tot].t=tot;a[tot].k=k;a[tot].pos=ans[0]; a[++tot].x=x2,a[tot].y=y1;a[tot].v=-1;a[tot].t=tot;a[tot].k=k;a[tot].pos=ans[0]; } } sort(a+1,a+tot+1); cdq(1,tot); FOR(i,1,ans[0])printf("%d\n",ans[i]); return 0; }