模板—K-D-tree(P2479 [SDOI2010]捉迷藏)
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
放一下‘天使玩偶’的标程:
#include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #include<cmath> #define LL long long using namespace std; int n,m,cmpid; struct point { int x[2]; friend bool operator < (point a,point b) {return a.x[cmpid]<b.x[cmpid];} }p[510000]; struct tree { point p; int mx[2],mn[2],l,r; #define l(x) tr[x].l #define r(x) tr[x].r #define p(x) tr[x].p }tr[10000000]; int dis(point a,point b){return abs(a.x[0]-b.x[0])+abs(a.x[1]-b.x[1]);} int min_dis(tree a,point b) { int x=max(a.mn[0]-b.x[0],0)+max(b.x[0]-a.mx[0],0); int y=max(a.mn[1]-b.x[1],0)+max(b.x[1]-a.mx[1],0); return x+y; } struct KD_tree { int root,tot,ans; #define INF 0x7fffffff void ask_min(point a,int x,int k) { if(!x)return;int tem; if((tem=dis(p(x),a))<ans)ans=tem; int l=l(x),r=r(x); if(a.x[k]>p(x).x[k])swap(l,r); if(min_dis(tr[l],a)<ans)ask_min(a,l,k^1); if(min_dis(tr[r],a)<ans)ask_min(a,r,k^1); } int ask_min(point a) { ans=INF;ask_min(a,root,0); return ans; } void updata(int x) { if(!x)return; if(l(x)) tr[x].mn[0]=min(tr[x].mn[0],tr[l(x)].mn[0]), tr[x].mn[1]=min(tr[x].mn[1],tr[l(x)].mn[1]), tr[x].mx[0]=max(tr[x].mx[0],tr[l(x)].mx[0]), tr[x].mx[1]=max(tr[x].mx[1],tr[l(x)].mx[1]); if(r(x)) tr[x].mn[0]=min(tr[x].mn[0],tr[r(x)].mn[0]), tr[x].mn[1]=min(tr[x].mn[1],tr[r(x)].mn[1]), tr[x].mx[0]=max(tr[x].mx[0],tr[r(x)].mx[0]), tr[x].mx[1]=max(tr[x].mx[1],tr[r(x)].mx[1]); } void build(int &x,int l,int r,int k) { if(l>r)return; x=++tot;int mid=(l+r)>>1; cmpid=k; nth_element(p+l,p+mid,p+r+1); p(x)=p[mid]; tr[x].mn[0]=tr[x].mx[0]=p(x).x[0]; tr[x].mn[1]=tr[x].mx[1]=p(x).x[1]; build(l(x),l,mid-1,k^1); build(r(x),mid+1,r,k^1); updata(x); } void build(){tot=0;build(root,1,n,0);} void insert(point a,int &x,int k) { if(!x) { x=++tot;p(x)=a; tr[x].mn[0]=tr[x].mx[0]=p(x).x[0]; tr[x].mn[1]=tr[x].mx[1]=p(x).x[1]; return; } if(a.x[k]<p(x).x[k])insert(a,l(x),k^1); else insert(a,r(x),k^1); updata(x); } void insert(point a){insert(a,root,0);} }T; signed main() { cin>>n>>m; for(int i=1;i<=n;i++)cin>>p[i].x[0]>>p[i].x[1]; T.build();int t,x,y; for(int i=1;i<=m;i++) { cin>>t>>x>>y; if(t==1)T.insert((point){x,y}); else cout<<T.ask_min((point){x,y})<<endl;; } }
波澜前,面不惊。