[BZOJ2648]=[BZOJ2716]SJY摆棋子
2016-02-23 23:41
363 查看
原题地址
Kdtree的带插入最邻近点查询.
轮流划分维度+暴力插入AC了,而且时间排名还比较靠前…
AC code:
Kdtree的带插入最邻近点查询.
轮流划分维度+暴力插入AC了,而且时间排名还比较靠前…
AC code:
#include <cstdio> #include <algorithm> using namespace std; const int K=2; const int N=1000010; const int INF=1<<29; int n,m,mn,tot,flg; struct Poi{ int d[K]; Poi() {} Poi(int x,int y) {d[0]=x;d[1]=y;} friend bool operator<(Poi x,Poi y){ return x.d[flg]<y.d[flg]; } }a ; struct nod{ Poi poi; int mxd[K],mnd[K]; nod *ch[2]; }pool ; 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]); } } } 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 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); } void insert(nod **p,Poi poi,int flag){ if(*p==NULL){ *p=&pool[tot++]; (*p)->poi=poi; for(int i=0;i<K;i++) (*p)->mxd[i]=(*p)->mnd[i]=poi.d[i]; return ; } if(poi.d[flag]<=(*p)->poi.d[flag]) insert(&(*p)->ch[0],poi,(flag+1)%K); else insert(&(*p)->ch[1],poi,(flag+1)%K); update(*p); } void query(nod *p,Poi poi){ int dis0=abs(p->poi.d[0]-poi.d[0])+abs(p->poi.d[1]-poi.d[1]),dis[2]; if(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) query(p->ch[t],poi); t^=1; if(p->ch[t]!=NULL&&dis[t]<mn) query(p->ch[t],poi); } }; int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) for(int j=0;j<K;j++) scanf("%d",&a[i].d[j]); Kdtree T; for(int i=1;i<=m;i++){ int t,x,y; scanf("%d%d%d",&t,&x,&y); if(t==1) T.insert(&T.root,Poi(x,y),0); else{ mn=INF; T.query(T.root,Poi(x,y)); printf("%d\n",mn); } } return 0; }
相关文章推荐
- windows基础编程 - 子控件之组合框
- HDU 1394 Minimum Inversion Number(线段树:单点更新,区间求和)
- POJ--3481 Double Queue
- VC6兼容性及打开文件崩溃问题解决
- 回调理解
- python(一)端口扫描器(二)
- hive install
- 折腾了ubuntu跟mac黑苹果
- 基于Dubbo框架构建分布式服务
- 【慕课笔记】第四章 JAVA中的集合框架(上) 第10节 学生选课—应用泛型管理课程(二)
- lua学习Day03
- Leetcode旅途二
- <<Android 开发艺术探索>> 第一章 Actiivty的生命周期和启动模式
- bootstrap-datepicker限定可选时间范围
- 不能将“this”指针从“const XXX”转为“XXX &”
- POJ--3253 Fence Repair
- 使用git客户端提交代码到github
- C++中使用空对象指针调用成员函数
- swift基本语法(总结提炼版)之006 Swift之 while循环
- HierarchyViewer结合merge标签优化布局结构