BZOJ 2716

http://www.lydsy.com/JudgeOnline/problem.php?id=2716

x坐标排序

时间cdq分治

y坐标树状数组维护

对于每次询问左下角的点维护前缀最大值x+y

然后坐标翻转做剩下三次操作

#include<cstdio>
#include<algorithm>
#define gc getchar()
#define FOR(i,s,t) for(register int i=s;i<=t;++i)
using std::sort;
inline int max(int a,int b){return a>b?a:b;}
inline int min(int a,int b){return a<b?a:b;} 
inline int abs(int x){return x>=0?x:-x;}
const int N=1200011,M=4000011,inf=(1<<27);
int ans[N];
int n,m,maxx;
struct point{
	int x,y,t,k,pos;
	inline bool operator<(point A)const{if(x!=A.x)return x<A.x;if(y!=A.y)return y<A.y; return t<A.t;}
}p[N],t[N];
namespace BIT{
	int tr[M];
	inline int lowbit(int x){return x&-x;}	
	inline void add(int x,int v){for(;x<=maxx;x+=lowbit(x))tr[x]=max(tr[x],v);}
	inline int query(int x){int ret=-inf;for(;x;x-=lowbit(x))ret=max(ret,tr[x]);return ret;}
	inline void del(int x){for(;x<=maxx;x+=lowbit(x))if(tr[x]!=-inf)tr[x]=-inf;else break;}
}
using namespace BIT;
inline void cdq(int l,int r){
	if(l==r)return;
	int mid=(l+r)>>1;
	int j=l,k=mid+1;
	FOR(i,l,r){
		if(p[i].k==1&&p[i].t<=mid)add(p[i].y,(p[i].x+p[i].y));
		if(p[i].k==2&&p[i].t>mid)ans[p[i].pos]=min(ans[p[i].pos],(p[i].x+p[i].y-query(p[i].y)));
	}
	FOR(i,l,r)if(p[i].k==1&&p[i].t<=mid)del(p[i].y);
	FOR(i,l,r)p[i].t<=mid?t[j++]=p[i]:t[k++]=p[i];
	FOR(i,l,r)p[i]=t[i];
	cdq(l,mid);cdq(mid+1,r);
}
inline int read(){
	char c;while(c=gc,c==' '||c=='\n');int data=c-48;
	while(c=gc,c>='0'&&c<='9')data=(data<<1)+(data<<3)+c-48;return data;
}
int main(){
	n=read();m=read();
	FOR(i,1,n){
		p[i].t=i;p[i].k=1;
		p[i].x=read();p[i].y=read();
		maxx=max(maxx,max(abs(p[i].x),abs(p[i].y)));
	}
	FOR(i,(n+1),(n+m)){
		p[i].k=read();p[i].x=read();p[i].y=read();
		p[i].t=i;
		maxx=max(maxx,max(abs(p[i].x),abs(p[i].y)));
		if(p[i].k==2){
			ans[++ans[0]]=inf;
			p[i].pos=ans[0];
		}
	}
	n+=m;
	++maxx;
	FOR(i,1,n)p[i].x+=maxx,p[i].y+=maxx;
	maxx<<=1;
	FOR(i,0,maxx)tr[i]=-inf;
	sort(p+1,p+n+1);cdq(1,n);
	FOR(i,1,n)p[i].y=maxx-p[i].y;sort(p+1,p+n+1);cdq(1,n);
	FOR(i,1,n)p[i].x=maxx-p[i].x;sort(p+1,p+n+1);cdq(1,n);
	FOR(i,1,n)p[i].y=maxx-p[i].y;sort(p+1,p+n+1);cdq(1,n);
	FOR(i,1,ans[0])printf("%d\n",ans[i]);
	return 0;
} 

  

 

posted @ 2017-12-07 09:49  Stump  阅读(145)  评论(0编辑  收藏  举报