1 #include<algorithm> 2 #include<iostream> 3 #include<cstdio> 4 #include<cmath> 5 #define LL long long 6 #define MAXN 1000100 7 using namespace std; 8 inline LL min(LL a,LL b){return a<b?a:b;} 9 int n,cmpid; 10 struct point 11 { 12 int x[2]; 13 friend bool operator < (point a,point b) 14 {return a.x[cmpid]<b.x[cmpid];} 15 }p[MAXN]; 16 struct tree 17 { 18 point p; 19 int mn[2],mx[2],l,r; 20 #define l(x) tr[x].l 21 #define r(x) tr[x].r 22 #define p(x) tr[x].p 23 }tr[MAXN]; 24 int Dis(point a,point b) 25 { 26 return abs(a.x[0]-b.x[0])+abs(a.x[1]-b.x[1]); 27 } 28 int min_dis(tree a,point b) 29 { 30 int x=max(a.mn[0]-b.x[0],0)+max(b.x[0]-a.mx[0],0); 31 int y=max(a.mn[1]-b.x[1],0)+max(b.x[1]-a.mx[1],0); 32 return x+y; 33 } 34 int max_dis(tree a,point b) 35 { 36 int x=max(abs(a.mx[0]-b.x[0]),abs(b.x[0]-a.mn[0])); 37 int y=max(abs(a.mx[1]-b.x[1]),abs(b.x[1]-a.mn[1])); 38 return x+y; 39 } 40 struct KDtree 41 { 42 int root,tot,ans; 43 #define INF 0x7fffffff 44 void ask_max(point a,int x,int k) 45 { 46 if(!x)return;int tem; 47 if((tem=Dis(p(x),a))>ans)ans=tem; 48 int l=l(x),r=r(x); 49 if(a.x[k]<p(x).x[k])swap(l,r); 50 if(max_dis(tr[l],a)>ans)ask_max(a,l,k^1); 51 if(max_dis(tr[r],a)>ans)ask_max(a,r,k^1); 52 } 53 int ask_max(point a) 54 { 55 ans=-INF; 56 ask_max(a,root,0); 57 return ans; 58 } 59 void ask_min(point a,int x,int k) 60 { 61 if(!x)return;int tem; 62 if((tem=Dis(p(x),a))<ans&&tem!=0)ans=tem; 63 int l=l(x),r=r(x); 64 if(a.x[k]>p(x).x[k])swap(l,r);//如果a在x有右半区间,先向右搜索。 65 if(min_dis(tr[l],a)<ans)ask_min(a,l,k^1); 66 if(min_dis(tr[r],a)<ans)ask_min(a,r,k^1); 67 } 68 int ask_min(point a) 69 { 70 ans=INF; 71 ask_min(a,root,0); 72 return ans; 73 } 74 void updata(int x) 75 { 76 if(!x)return; 77 if(l(x)) 78 tr[x].mn[0]=min(tr[x].mn[0],tr[l(x)].mn[0]), 79 tr[x].mn[1]=min(tr[x].mn[1],tr[l(x)].mn[1]), 80 tr[x].mx[0]=max(tr[x].mx[0],tr[l(x)].mx[0]), 81 tr[x].mx[1]=max(tr[x].mx[1],tr[l(x)].mx[1]); 82 if(r(x)) 83 tr[x].mn[0]=min(tr[x].mn[0],tr[r(x)].mn[0]), 84 tr[x].mn[1]=min(tr[x].mn[1],tr[r(x)].mn[1]), 85 tr[x].mx[0]=max(tr[x].mx[0],tr[r(x)].mx[0]), 86 tr[x].mx[1]=max(tr[x].mx[1],tr[r(x)].mx[1]); 87 } 88 void build(int &x,int l,int r,int k) 89 { 90 if(l>r)return; 91 x=++tot;int mid=(l+r)>>1; 92 cmpid=k; 93 nth_element(p+l,p+mid,p+r+1); 94 p(x)=p[mid]; 95 tr[x].mn[0]=tr[x].mx[0]=p(x).x[0]; 96 tr[x].mn[1]=tr[x].mx[1]=p(x).x[1]; 97 build(l(x),l,mid-1,k^1); 98 build(r(x),mid+1,r,k^1); 99 updata(x); 100 } 101 void build() 102 { 103 tot=0; 104 build(root,1,n,0); 105 } 106 }T; 107 signed main() 108 { 109 cin>>n; 110 for(int i=1;i<=n;i++) 111 cin>>p[i].x[0]>>p[i].x[1]; 112 T.build(); 113 LL ans=INF; 114 for(int i=1;i<=n;i++) 115 { 116 ans=min(ans,T.ask_max(p[i])-T.ask_min(p[i])); 117 } 118 cout<<ans<<endl; 119 } 120
模板—K-D-tree(P2479 [SDOI2010]捉迷藏)
猜你喜欢
转载自www.cnblogs.com/Al-Ca/p/11297379.html
今日推荐
周排行