BZOJ1941: [Sdoi2010]Hide and Seek kdtree
2017-01-03 15:26
453 查看
题目大意:给定n个点,求其中一个点使得到其它所有点中的最远距离和最近距离差值最小,距离定义为曼哈顿距离。
N<=500000,0<=X,Y<=10^8
用kdtree暴力枚举每一个点即可。注意算距离时不能算自己。
最远距离的估价为max(abs(x-xmin)、abs(x-xmax))+max(abs(y-ymin)、abs(y-ymax))。
N<=500000,0<=X,Y<=10^8
用kdtree暴力枚举每一个点即可。注意算距离时不能算自己。
最远距离的估价为max(abs(x-xmin)、abs(x-xmax))+max(abs(y-ymin)、abs(y-ymax))。
#include<cstdio> #include<algorithm> using namespace std; typedef int pnt[2]; inline int dis(pnt a,pnt b) { return abs(a[0]-b[0])+abs(a[1]-b[1]); } struct node { pnt v,mn,mx; node *l,*r; node(int x,int y):l(0),r(0) { v[0]=mn[0]=mx[0]=x, v[1]=mn[1]=mx[1]=y; } static const int inf=0x7fffffff; inline void up() { if(l) { mn[0]=min(mn[0],l->mn[0]); mn[1]=min(mn[1],l->mn[1]); mx[0]=max(mx[0],l->mx[0]); mx[1]=max(mx[1],l->mx[1]); } if(r) { mn[0]=min(mn[0],r->mn[0]); mn[1]=min(mn[1],r->mn[1]); mx[0]=max(mx[0],r->mx[0]); mx[1]=max(mx[1],r->mx[1]); } } inline int min_dis(pnt p) { if(!this) return inf; int res=0; if(p[0]<mn[0]) res+=mn[0]-p[0]; else if(mx[0]<p[0]) res+=p[0]-mx[0]; if(p[1]<mn[1]) res+=mn[1]-p[1]; else if(mx[1]<p[1]) res+=p[1]-mx[1]; return res; } inline int max_dis(pnt p) { return this?max(abs(p[0]-mn[0]),abs(mx[0]-p[0]))+max(abs(p[1]-mn[1]),abs(mx[1]-p[1])):-inf; } void get_min(pnt p,int &ans) { if(!this) return; if(p[0]!=v[0]||p[1]!=v[1]) ans=min(ans,dis(p,v)); int ldis=l->min_dis(p),rdis=r->min_dis(p); if(ldis<rdis) { if(ldis<ans) l->get_min(p,ans); if(rdis<ans) r->get_min(p,ans); } else { if(rdis<ans) r->get_min(p,ans); if(ldis<ans) l->get_min(p,ans); } } void get_max(pnt p,int &ans) { if(!this) return; if(p[0]!=v[0]||p[1]!=v[1]) ans=max(ans,dis(p,v)); int ldis=l->max_dis(p),rdis=r->max_dis(p); if(ldis>rdis) { if(ldis>ans) l->get_max(p,ans); if(rdis>ans) r->get_max(p,ans); } else { if(rdis>ans) r->get_max(p,ans); if(ldis>ans) l->get_max(p,ans); } } }; typedef unsigned long long ll; inline bool cmp0(const ll &a,const ll &b) { return int(a)<int(b); } inline bool cmp1(const ll &a,const ll &b) { return int(a>>32)<int(b>>32); } struct kdtree { node *rt; static node* build(ll *l,ll *r,bool k) { if(l==r) return 0; ll* mid=l+(r-l>>1); nth_element(l,mid,r,k?cmp1:cmp0); node *kre=new node(int(*mid),int((*mid)>>32)); kre->l=build(l,mid,!k); kre->r=build(mid+1,r,!k); kre->up(); return kre; } kdtree(ll a[],int len):rt(build(a,a+len,0)){} inline int query_min(int x,int y) { int ans=node::inf; pnt p={x,y}; rt->get_min(p,ans); return ans; } inline int query_max(int x,int y) { int ans=-node::inf; pnt p={x,y}; rt->get_max(p,ans); return ans; } }; int n; ll __p[500000]; int main() { scanf("%d",&n); unsigned int x; for(int i=0;i<n;++i) { scanf("%llu%u",__p+i,&x); __p[i]|=ll(x)<<32; } kdtree tr(__p,n); int ans=node::inf; for(int i=0;i<n;++i) { int mid=tr.query_min(int(__p[i]),int(__p[i]>>32)); int mad=tr.query_max(int(__p[i]),int(__p[i]>>32)); if(mad-mid<ans) ans=mad-mid; } printf("%d\n",ans); return 0; }
相关文章推荐
- [BZOJ1941][Sdoi2010]Hide and Seek(KD-tree)
- [KD-TREE] BZOJ 1941 [Sdoi2010]Hide and Seek
- bzoj1941: [Sdoi2010]Hide and Seek KD-tree
- bzoj 1941: [Sdoi2010]Hide and Seek KDtree
- [bzoj1941][Sdoi2010]Hide and Seek_KD-Tree
- 【BZOJ1941】[Sdoi2010]Hide and Seek KDtree
- BZOJ 1941: [Sdoi2010]Hide and Seek kdtree
- [BZOJ1941][Sdoi2010]Hide and Seek(kd-tree)
- 【kd-tree】bzoj1941 [Sdoi2010]Hide and Seek
- bzoj 1941: [Sdoi2010]Hide and Seek (KD-tree)
- BZOJ 1941 Sdoi2010 Hide and Seek K-Dimensional-Tree
- 【SDOI2010】【BZOJ1941】Hide and Seek
- bzoj1941 [Sdoi2010]Hide and Seek
- BZOJ1941: [Sdoi2010]Hide and Seek
- BZOJ1941 [Sdoi2010]Hide and Seek
- 【bzoj1941】【sdoi2010】【Hide and Seek】【kd树】
- 【bzoj1941】 Sdoi2010—Hide and Seek
- bzoj:1941: [Sdoi2010]Hide and Seek
- 【bzoj1941】【Sdoi2010】Hide and Seek
- BZOJ 1941 [Sdoi2010] Hide and Seek