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