Solution
根据数据范围,大概需要O(nlogn)的算法,考虑数据结构
对于一个点(xi,yi)来说,其他点到它的距离为|xi-x|+|yi-y|
可以分为四种情况
- xi>=x && yi>=y:|xi-x|+|yi-y|=xi-x+yi-y
- xi>=x && yi<y: |xi-x|+|yi-y|=xi-x+y-yi
- xi<=x && yi>=y:|xi-x|+|yi-y|=x-xi+yi-y
- xi<=x && yi<y: |xi-x|+|yi-y|=x-xi+y-yi
发现每个式子都有确定的一部分和不确定的一部分
于是离散 y ,按 x 从小到大排序,用一个数据结构维护最小值和最大值
Code
#include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> using namespace std; const int N=1e5+10; struct node { int x,y,re; bool operator <(const node &o)const { return x<o.x; } }a[N],d[N]; struct mode { int lc,rc,l,r; int mi,ma; }f[N*2]; int cnt,n,mi[N],ma[N],rt,tot; void build(int &g,int l,int r) { g=++tot; f[g].l=l,f[g].r=r; if(l==r) return; int mid=(l+r)>>1; build(f[g].lc,l,mid); build(f[g].rc,mid+1,r); } int get_mi(int g,int l,int r) { if(f[g].l>=l && f[g].r<=r) return f[g].mi; int mid=(f[g].l+f[g].r)>>1; if(r<=mid) return get_mi(f[g].lc,l,r); else if(l>mid) return get_mi(f[g].rc,l,r); else return min(get_mi(f[g].lc,l,mid),get_mi(f[g].rc,mid+1,r)); } int get_ma(int g,int l,int r) { if(f[g].l>=l && f[g].r<=r) return f[g].ma; int mid=(f[g].l+f[g].r)>>1; if(r<=mid) return get_ma(f[g].lc,l,r); else if(l>mid) return get_ma(f[g].rc,l,r); else return max(get_ma(f[g].lc,l,mid),get_ma(f[g].rc,mid+1,r)); } void push_up(int g) { int lc=f[g].lc,rc=f[g].rc; f[g].mi=min(f[lc].mi,f[rc].mi); f[g].ma=max(f[lc].ma,f[rc].ma); } void add(int g,int x,int k) { if(f[g].l==f[g].r) { f[g].mi=min(f[g].mi,k); f[g].ma=max(f[g].ma,k); return ; } int mid=(f[g].l+f[g].r)>>1; if(x<=mid) add(f[g].lc,x,k); else add(f[g].rc,x,k); push_up(g); } void clear() { for(int i=1;i<=tot;i++) f[i].mi=999999999,f[i].ma=-999999999; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { mi[i]=999999999,ma[i]=-999999999; scanf("%d%d",&d[i].x,&d[i].y); d[i].re=d[i].y; a[i]=(node){d[i].y,i,0}; } sort(a+1,a+1+n); for(int i=1;i<=n;i++) { if(i==1 || a[i].x!=a[i-1].x) cnt++; d[a[i].y].y=cnt; } sort(d+1,d+1+n); //x<xi: (1)y<=yi xi-x+yi-y -x-y (2)y>yi xi-x+y-yi -x+y build(rt,1,cnt); clear(); for(int i=1;i<=n;i++) { mi[i]=min(mi[i],d[i].x+d[i].re+get_mi(rt,1,d[i].y)); ma[i]=max(ma[i],d[i].x+d[i].re+get_ma(rt,1,d[i].y)); add(rt,d[i].y,-d[i].x-d[i].re); } clear(); for(int i=1;i<=n;i++) { add(rt,d[i].y,-d[i].x+d[i].re); if(d[i].y==cnt) continue; mi[i]=min(mi[i],d[i].x-d[i].re+get_mi(rt,d[i].y+1,cnt)); ma[i]=max(ma[i],d[i].x-d[i].re+get_ma(rt,d[i].y+1,cnt)); } clear(); //x>xi: (1)y>=yi x-xi+y-yi x+y (2)y<yi x-xi+yi-y x-y for(int i=n;i;i--) { mi[i]=min(mi[i],-d[i].x-d[i].re+get_mi(rt,d[i].y,cnt)); ma[i]=max(ma[i],-d[i].x-d[i].re+get_ma(rt,d[i].y,cnt)); add(rt,d[i].y,d[i].x+d[i].re); } clear(); for(int i=n;i;i--) { add(rt,d[i].y,d[i].x-d[i].re); if(d[i].y==1) continue; mi[i]=min(mi[i],-d[i].x+d[i].re+get_mi(rt,1,d[i].y-1)); ma[i]=max(ma[i],-d[i].x+d[i].re+get_ma(rt,1,d[i].y-1)); } int ans=999999999; for(int i=1;i<=n;i++) ans=min(ans,ma[i]-mi[i]); printf("%d\n",ans); return 0; }
- xi>=x && yi>=y:|xi-x|+|yi-y|=xi-x+yi-y