Code:
#include<bits/stdc++.h> #define maxn 200000 #define inf 1000000000 using namespace std; void getmin(int &a,int b) { if(b<a) a=b; } void getmax(int &a,int b) { if(b>a) a=b; } void setIO(string s) { string in=s+".in"; string out=s+".out"; freopen(in.c_str(),"r",stdin); freopen(out.c_str(),"w",stdout); } namespace KDtree { #define lson t[x].ch[0] #define rson t[x].ch[1] #define mid ((l+r)>>1) int d,ansmin,ansmax,answer; struct Node { int ch[2],minv[2],maxv[2],p[2]; }t[maxn],T; bool cmp(Node a,Node b) { if(a.p[d] == b.p[d]) return a.p[d^1] < b.p[d^1]; return a.p[d] < b.p[d]; } void pushup(int o,int x) { getmin(t[o].minv[0], t[x].minv[0]); getmax(t[o].maxv[0], t[x].maxv[0]); getmin(t[o].minv[1], t[x].minv[1]); getmax(t[o].maxv[1], t[x].maxv[1]); } int build(int l,int r,int o) { d=o; nth_element(t+l,t+mid,t+1+r,cmp); t[mid].minv[0]=t[mid].maxv[0]=t[mid].p[0]; t[mid].minv[1]=t[mid].maxv[1]=t[mid].p[1]; t[mid].ch[0]=t[mid].ch[1]=0; if(l<mid) { t[mid].ch[0]=build(l,mid-1,o^1); pushup(mid,t[mid].ch[0]); } if(r>mid) { t[mid].ch[1]=build(mid+1,r,o^1); pushup(mid,t[mid].ch[1]); } return mid; } int _min(Node a) { int ans=0; for(int i=0;i<2;++i) { ans += max(T.p[i]-a.maxv[i], 0); ans += max(a.minv[i]-T.p[i], 0); } return ans; } int _max(Node a) { int ans=0; for(int i=0;i<2;++i) { ans += max(abs(T.p[i]-a.minv[i]), abs(T.p[i]-a.maxv[i])); } return ans; } void qmin(int x,int x1,int y1) { int dn=abs(t[x].p[0]-x1) + abs(t[x].p[1]-y1),dl,dr; if(dn>0) getmin(ansmin,dn); dl=lson?_min(t[lson]):inf; dr=rson?_min(t[rson]):inf; if(dl<dr) { if(dl<ansmin) qmin(lson,x1,y1); if(dr<ansmin) qmin(rson,x1,y1); } else { if(dr<ansmin) qmin(rson,x1,y1); if(dl<ansmin) qmin(lson,x1,y1); } } void qmax(int x,int x1,int y1) { int dn=abs(t[x].p[0]-x1) + abs(t[x].p[1]-y1),dl,dr; getmax(ansmax, dn); dl=lson?_max(t[lson]):-inf; dr=rson?_max(t[rson]):-inf; if(dl>dr) { if(dl>ansmax) qmax(lson,x1,y1); if(dr>ansmax) qmax(rson,x1,y1); } else { if(dr>ansmax) qmax(rson,x1,y1); if(dl>ansmax) qmax(lson,x1,y1); } } void solve(int i,int rt) { T=t[i], ansmin=inf,ansmax=-inf; qmin(rt, T.p[0], T.p[1]); qmax(rt, T.p[0], T.p[1]); getmin(answer, ansmax-ansmin); } }; int main() { //setIO("A"); int n,root,i; KDtree::answer=inf; scanf("%d",&n); for(i=1;i<=n;++i) scanf("%d%d",&KDtree::t[i].p[0],&KDtree::t[i].p[1]); root=KDtree::build(1,n,0); for(i=1;i<=n;++i) { KDtree::solve(i,root); } printf("%d\n",KDtree::answer); return 0; }
BZOJ 1941: [Sdoi2010]Hide and Seek KDtree + 估价函数
原文:https://www.cnblogs.com/guangheli/p/11054479.html