BZOJ 1941 [Sdoi2010]Hide and Seek
题解:每个点向四个方向分别求最远点和最近点,用树状数组维护即可
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=500009; const int oo=1000000000; int n; int ans=oo; struct Point{ int x,y; int mindist,maxdist; }p[maxn]; bool cmpx(const Point &rhs1,const Point &rhs2){ if(rhs1.x==rhs2.x)return rhs1.y<rhs2.y; else return rhs1.x<rhs2.x; } inline int lowbit(int x){ return x&(-x); } int b[maxn],nn; struct FenwickTree{ int c[maxn]; void Addp(int x,int val){ while(x<=nn){ c[x]=max(c[x],val); x+=lowbit(x); } } int Query(int x){ int ret=-oo; while(x){ ret=max(ret,c[x]); x-=lowbit(x); } return ret; } void Fenwickinit(){ for(int i=0;i<maxn;++i)c[i]=-oo; } }T[3]; void Sol(){ T[1].Fenwickinit(); T[2].Fenwickinit(); for(int i=1;i<=n;++i)b[i]=p[i].y; sort(b+1,b+1+n); nn=unique(b+1,b+1+n)-b-1; for(int i=1;i<=n;++i){ int pla=lower_bound(b+1,b+1+nn,p[i].y)-b; int tm1=T[1].Query(pla); int tm2=-T[2].Query(pla); p[i].mindist=min(p[i].mindist,p[i].x+p[i].y-tm1); p[i].maxdist=max(p[i].maxdist,p[i].x+p[i].y-tm2); T[1].Addp(pla,p[i].x+p[i].y); T[2].Addp(pla,-p[i].x-p[i].y); } } int main(){ scanf("%d",&n); for(int i=1;i<=n;++i){ scanf("%d%d",&p[i].x,&p[i].y); p[i].mindist=oo; p[i].maxdist=-oo; } sort(p+1,p+1+n,cmpx); Sol(); for(int i=1;i<=n;++i)p[i].y=-p[i].y; sort(p+1,p+1+n,cmpx); Sol(); for(int i=1;i<=n;++i)p[i].y=-p[i].y; for(int i=1;i<=n;++i)p[i].x=-p[i].x; sort(p+1,p+1+n,cmpx); Sol(); for(int i=1;i<=n;++i)p[i].y=-p[i].y; sort(p+1,p+1+n,cmpx); Sol(); for(int i=1;i<=n;++i){ ans=min(ans,p[i].maxdist-p[i].mindist); } printf("%d\n",ans); return 0; }
致歉:笔者已经意识到这是一篇几乎没有价值的文章,给您的阅读带来不好的体验,并且干扰了您的搜索环境,非常抱歉!