[BZOJ1941][Sdoi2010]Hide and Seek
来源:互联网 发布:网络少儿外教一对一 编辑:程序博客网 时间:2024/05/16 10:56
原题地址
Kdtree第一题.
讲一下Kdtree:
Kdtree的用途是对高维向量(点)进行各种索引.
建树操作:轮流选择维度(资料上说要按最大方差来选维度,然而各种题解都是轮流选择维度…),用nth_element()对点进行划分,然后建树、递归,回溯时维护边界(边界意义:一个二维点的边界信息可以形象地理解为一个包含该点所在子树中的所有点围成的一个最小矩形,高维类比).
查找最近/远点的操作:有了边界,我们可以很方便地求出查询点与某子树所管辖空间的最近/最远距离(具体看代码),然后进行相应的递归、回溯(具体看代码).
研究表明,一次该操作的时间复杂度为
(来自资料).
今天手感不错,1A了 233
AC code:
#include <cstdio>#include <algorithm>using namespace std;const int K=2;const int N=1000010;const int INF=1<<29;int n,mx,mn,ans=INF,tot,flg;struct Poi{ int d[K]; friend bool operator<(Poi x,Poi y){ return x.d[flg]<y.d[flg]; }}a[N];struct nod{ Poi poi; int mxd[K],mnd[K]; nod *ch[2];}pool[N];int getdis(Poi x,Poi y){ int sum=0; for(int i=0;i<K;i++) sum+=abs(x.d[i]-y.d[i]); return sum;}struct Kdtree{ nod *root; Kdtree(){ build(&root,1,n,0); }; void update(nod *p){ for(int i=0;i<K;i++){ p->mxd[i]=p->mnd[i]=p->poi.d[i]; if(p->ch[0]!=NULL){ p->mxd[i]=max(p->mxd[i],p->ch[0]->mxd[i]); p->mnd[i]=min(p->mnd[i],p->ch[0]->mnd[i]); } if(p->ch[1]!=NULL){ p->mxd[i]=max(p->mxd[i],p->ch[1]->mxd[i]); p->mnd[i]=min(p->mnd[i],p->ch[1]->mnd[i]); } } } void build(nod **p,int L,int R,int flag){ if(L>R) return ; *p=&pool[tot++]; if(L==R){ (*p)->poi=a[L]; for(int i=0;i<K;i++) (*p)->mxd[i]=(*p)->mnd[i]=a[L].d[i]; return ; } int M=(L+R)>>1; flg=flag; nth_element(a+L,a+M,a+R+1); (*p)->poi=a[M]; build(&(*p)->ch[0],L,M-1,(flag+1)%K); build(&(*p)->ch[1],M+1,R,(flag+1)%K); update(*p); } int maxdis(nod *p,Poi poi){ int sum=0; for(int i=0;i<K;i++) sum+=max(abs(p->mxd[i]-poi.d[i]),abs(p->mnd[i]-poi.d[i])); return sum; } int mindis(nod *p,Poi poi){ int sum=0; for(int i=0;i<K;i++){ if(poi.d[i]<p->mnd[i]) sum+=p->mnd[i]-poi.d[i]; else if(poi.d[i]>p->mxd[i]) sum+=poi.d[i]-p->mxd[i]; } return sum; } void getmax(nod *p,Poi poi){ int dis0=getdis(p->poi,poi),dis[2]; if(dis0>mx) mx=dis0; if(p->ch[0]!=NULL) dis[0]=maxdis(p->ch[0],poi); if(p->ch[1]!=NULL) dis[1]=maxdis(p->ch[1],poi); bool t=dis[0]<dis[1]; if(p->ch[t]!=NULL&&dis[t]>mx) getmax(p->ch[t],poi); t^=1; if(p->ch[t]!=NULL&&dis[t]>mx) getmax(p->ch[t],poi); } void getmin(nod *p,Poi poi){ int dis0=getdis(p->poi,poi),dis[2]; if(dis0&&dis0<mn) mn=dis0; if(p->ch[0]!=NULL) dis[0]=mindis(p->ch[0],poi); if(p->ch[1]!=NULL) dis[1]=mindis(p->ch[1],poi); bool t=dis[0]>dis[1]; if(p->ch[t]!=NULL&&dis[t]<mn) getmin(p->ch[t],poi); t^=1; if(p->ch[t]!=NULL&&dis[t]<mn) getmin(p->ch[t],poi); }};int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d%d",&a[i].d[0],&a[i].d[1]); Kdtree T; for(int i=1;i<=n;i++){ mx=0;mn=INF; T.getmax(T.root,a[i]); T.getmin(T.root,a[i]); if(mx-mn<ans) ans=mx-mn; } printf("%d\n",ans); return 0;}
0 0
- [BZOJ1941][Sdoi2010]Hide and Seek
- [bzoj1941][SDOI2010]Hide and Seek
- 【SDOI2010】【BZOJ1941】Hide and Seek
- bzoj1941: [Sdoi2010]Hide and Seek
- 【SDOI2010】bzoj1941 Hide and Seek
- 【bzoj1941】[Sdoi2010]Hide and Seek
- bzoj1941 [Sdoi2010]Hide and Seek
- bzoj1941: [Sdoi2010]Hide and Seek KD-tree
- 【bzoj1941】【sdoi2010】【Hide and Seek】【kd树】
- BZOJ1941: [Sdoi2010]Hide and Seek kdtree
- 【BZOJ1941】【SDOI2010】Hide and Seek、KDTree【数组版】 模板、
- Bzoj1941:[Sdoi2010]Hide and Seek:K-D-Tree
- [BZOJ1941][Sdoi2010]Hide and Seek(kd-tree)
- [BZOJ1941][SDOI2010]Hide and Seek(线段树)
- [BZOJ1941][Sdoi2010]Hide and Seek(KD-tree)
- bzoj1941 Hide and Seek(kd_Tree模板题)
- [bzoj1941][kd-tree]Hide and Seek
- 1941: [Sdoi2010]Hide and Seek
- 58. Length of Last Word
- 防止自己网站被拿来钓鱼
- Linux时间函数之gettimeofday()函数之使用方法
- JSP内置对象详解
- 每日练习——2016.2.23
- [BZOJ1941][Sdoi2010]Hide and Seek
- win10 配置 java8
- RPCA(续)
- 重庆万科西九业主总群 52412842
- 从官方文档学《Freemarker》(1)
- Android流媒体播放器介绍
- 手把手入门神经网络系列(1)_从初等数学的角度初探神经网络
- hdu1171(多重背包)
- android中的类加载器,以及加载机制