BZOJ - 1941 Hide and Seek (kd树)
kd树模板题,求二维空间上的最远点/最近点。
对所有点建立kd树,分别查询每个点即可。单次查询期望时间复杂度$O(logn)$
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int N=5e5+10,inf=0x3f3f3f3f; 5 int n,ls[N],rs[N],mx[N][2],mi[N][2],rt,ans; 6 struct P {int x[2];} a[N]; 7 bool cmpx(P a,P b) {return a.x[0]<b.x[0];} 8 bool cmpy(P a,P b) {return a.x[1]<b.x[1];} 9 int dis(P a,P b) {return abs(a.x[0]-b.x[0])+abs(a.x[1]-b.x[1]);} 10 void pu(int u) { 11 for(int i=0; i<2; ++i) { 12 mx[u][i]=max(a[u].x[i],max(mx[ls[u]][i],mx[rs[u]][i])); 13 mi[u][i]=min(a[u].x[i],min(mi[ls[u]][i],mi[rs[u]][i])); 14 } 15 } 16 void build(int& u,int f=0,int l=1,int r=n) { 17 if(l>r) {u=0; return;} 18 int mid=(l+r)>>1; 19 u=mid; 20 if(l==r) {for(int i=0; i<2; ++i)mx[u][i]=mi[u][i]=a[u].x[i]; return;} 21 nth_element(a+l,a+mid,a+r+1,!f?cmpx:cmpy); 22 build(ls[u],f^1,l,mid-1),build(rs[u],f^1,mid+1,r); 23 pu(u); 24 } 25 int maxd(P p,int u) { 26 int ret=0; 27 for(int i=0; i<2; ++i)ret+=max(abs(p.x[i]-mx[u][i]),abs(p.x[i]-mi[u][i])); 28 return ret; 29 } 30 int mind(P p,int u) { 31 int ret=0; 32 for(int i=0; i<2; ++i) { 33 if(mx[u][i]<p.x[i])ret+=p.x[i]-mx[u][i]; 34 if(mi[u][i]>p.x[i])ret+=mi[u][i]-p.x[i]; 35 } 36 return ret; 37 } 38 void qrymaxd(int t,int& x,int u=rt,int f=0) { 39 if(u!=t)x=max(x,dis(a[t],a[u])); 40 int dl=0,dr=0; 41 if(ls[u])dl=maxd(a[t],ls[u]); 42 if(rs[u])dr=maxd(a[t],rs[u]); 43 if(dl>dr) {if(dl>x)qrymaxd(t,x,ls[u],f^1); if(dr>x)qrymaxd(t,x,rs[u],f^1);} 44 else {if(dr>x)qrymaxd(t,x,rs[u],f^1); if(dl>x)qrymaxd(t,x,ls[u],f^1);} 45 } 46 void qrymind(int t,int& x,int u=rt,int f=0) { 47 if(u!=t)x=min(x,dis(a[t],a[u])); 48 int dl=inf,dr=inf; 49 if(ls[u])dl=mind(a[t],ls[u]); 50 if(rs[u])dr=mind(a[t],rs[u]); 51 if(dl<dr) {if(dl<x)qrymind(t,x,ls[u],f^1); if(dr<x)qrymind(t,x,rs[u],f^1);} 52 else {if(dr<x)qrymind(t,x,rs[u],f^1); if(dl<x)qrymind(t,x,ls[u],f^1);} 53 } 54 int main() { 55 mx[0][0]=mx[0][1]=~inf,mi[0][0]=mi[0][1]=inf; 56 scanf("%d",&n); 57 for(int i=1; i<=n; ++i)scanf("%d%d",&a[i].x[0],&a[i].x[1]); 58 build(rt); 59 ans=inf; 60 for(int i=1; i<=n; ++i) { 61 int mi=inf,mx=0; 62 qrymaxd(i,mx),qrymind(i,mi); 63 ans=min(ans,mx-mi); 64 } 65 printf("%d\n",ans); 66 return 0; 67 }