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 }

 

posted @ 2019-04-06 15:20  jrltx  阅读(224)  评论(0编辑  收藏  举报