一开始看错题了
其实是:给定n个点,从中找一个点,使得其他所有点到它距离的最大值与最小值之差最小。
利用KD-Tree暴力求出每个点的答案(找离它最近的点以及最远的点(当然只关心距离))
然后……两个过程分开写……
注意一下最近的点的距离不能是0(然而我一开始用 if (o==tmp) return INF; 就WA了……)(这里o是当前搜索到的点,tmp是枚举的起始点)
1 /************************************************************** 2 Problem: 1941 3 User: Tunix 4 Language: C++ 5 Result: Accepted 6 Time:1484 ms 7 Memory:16900 kb 8 ****************************************************************/ 9 10 //BZOJ 1941 11 #include<cstdio> 12 #include<cstring> 13 #include<cstdlib> 14 #include<iostream> 15 #include<algorithm> 16 #define rep(i,n) for(int i=0;i<n;++i) 17 #define F(i,j,n) for(int i=j;i<=n;++i) 18 #define D(i,j,n) for(int i=j;i>=n;--i) 19 #define pb push_back 20 using namespace std; 21 typedef long long LL; 22 inline int getint(){ 23 int r=1,v=0; char ch=getchar(); 24 for(;!isdigit(ch);ch=getchar()) if (ch=='-') r=-1; 25 for(; isdigit(ch);ch=getchar()) v=v*10-'0'+ch; 26 return r*v; 27 } 28 const int N=500010,INF=1e9; 29 /*******************template********************/ 30 31 struct node{ 32 int d[2],mn[2],mx[2],l,r; 33 int& operator [] (int x){return d[x];} 34 void read(){d[0]=getint(); d[1]=getint();} 35 }t[N]; 36 int n,m,D,root,tmp,ask_mx,ask_mn; 37 bool operator < (node a,node b){return a[D]<b[D];} 38 #define L t[o].l 39 #define R t[o].r 40 #define mid (l+r>>1) 41 void Push_up(int o){ 42 F(i,0,1){ 43 t[o].mn[i]=min(t[o].mn[i],min(t[L].mn[i],t[R].mn[i])); 44 t[o].mx[i]=max(t[o].mx[i],max(t[L].mx[i],t[R].mx[i])); 45 } 46 } 47 48 int build(int l,int r,int dir){ 49 D=dir; 50 nth_element(t+l,t+mid,t+r+1); 51 int o=mid; 52 F(i,0,1) t[o].mn[i]=t[o].mx[i]=t[o][i]; 53 if (l<mid) L=build(l,mid-1,dir^1); 54 if (mid<r) R=build(mid+1,r,dir^1); 55 Push_up(o); 56 return o; 57 } 58 59 int dis(int a){return abs(t[a][0]-t[tmp][0])+abs(t[a][1]-t[tmp][1]);} 60 int calc_mn(int o){ 61 if (!o) return INF; 62 int ans=0; 63 F(i,0,1) ans+=max(0,t[o].mn[i]-t[tmp][i]); 64 F(i,0,1) ans+=max(0,t[tmp][i]-t[o].mx[i]); 65 return ans; 66 } 67 68 void query_mn(int o){ 69 if (!o) return; 70 int dl=calc_mn(L),dr=calc_mn(R),d0=dis(o); 71 if (d0) ask_mn=min(ask_mn,d0); 72 if (dl<dr){ 73 if (dl<ask_mn) query_mn(L); 74 if (dr<ask_mn) query_mn(R); 75 }else{ 76 if (dr<ask_mn) query_mn(R); 77 if (dl<ask_mn) query_mn(L); 78 } 79 } 80 81 int calc_mx(int o){ 82 if (!o) return -INF; 83 int ans=0; 84 F(i,0,1) ans+=max(abs(t[o].mn[i]-t[tmp][i]),abs(t[o].mx[i]-t[tmp][i])); 85 return ans; 86 } 87 void query_mx(int o){ 88 if (!o) return; 89 int dl=calc_mx(L),dr=calc_mx(R),d0=dis(o); 90 ask_mx=max(ask_mx,d0); 91 if (dl>dr){ 92 if (dl>ask_mx) query_mx(L); 93 if (dr>ask_mx) query_mx(R); 94 }else{ 95 if (dr>ask_mx) query_mx(R); 96 if (dl>ask_mx) query_mx(L); 97 } 98 } 99 100 int main(){ 101 #ifndef ONLINE_JUDGE 102 freopen("1941.in","r",stdin); 103 freopen("1941.out","w",stdout); 104 #endif 105 n=getint(); 106 F(i,1,n) t[i].read(); 107 F(i,0,1) t[0].mn[i]=INF,t[0].mx[i]=-INF; 108 root=build(1,n,1); 109 int ans=INF; 110 F(i,1,n){ 111 ask_mn=INF; ask_mx=-INF; 112 tmp=i; 113 query_mn(root); 114 query_mx(root); 115 // printf("%d %d\n",ask_mx,ask_mn); 116 ans=min(ans,ask_mx-ask_mn); 117 } 118 printf("%d\n",ans); 119 return 0; 120 }