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;
} 

  

posted @ 2017-12-06 10:44  Stump  阅读(155)  评论(0编辑  收藏  举报