终于找到了一个kd树的题、、来看看

k-d树原理还是不难的,就是代码技巧比较多可能可读性比较差

它就是把一个平面分成:

找最接近的点原理是利用极值矩形:

这个题就是k-d树板子题了、

下面的注释很详细

码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define N 1000005
#define inf 1000000000
using namespace std;
int xycmp,i,n,m,ans,rt,op;struct dian
{                              //注意:下标范围为[2]的  0指的是x坐标  1指的是y坐标
int xiao[2],da[2],xy[2];
}d[N];                   //对于d集的:只有xy有用,指每个点读入的坐标   bool cmp(dian x,dian y)
{   //cout<<xycmp<<" ";return (x.xy[xycmp]<y.xy[xycmp]);                            //比较的是这一次比较的坐标的大小
}struct kdtree
{int xia[N][2];   //指向这个节点的两个儿子 dian s[N],q;       //对于s集的:   xiao  指的是矩形左下角的坐标集    da指的是矩形右上角的点集      xy指的是这个点的坐标 void upd(int now)  //维护矩形 {int l=xia[now][0],r=xia[now][1]; for(int i=0;i<2;i++)//依次循环 x、y坐标 {if(l){s[now].da[i]=max(s[l].da[i],s[now].da[i]);s[now].xiao[i]=min(s[now].xiao[i],s[l].xiao[i]);} //如果有左儿子,就取一遍左儿子x、y  矩形  的   坐标最值  再取最值 if(r){s[now].da[i]=max(s[r].da[i],s[now].da[i]);s[now].xiao[i]=min(s[now].xiao[i],s[r].xiao[i]);}//如果有右儿子,就取一遍右儿子x、y  矩形  的   坐标最值  再取最值 }}void add(int now,dian t)//添加 {for(int i=0;i<2;i++)s[now].xiao[i]=s[now].da[i]=s[now].xy[i]=t.xy[i]; //初始化最大、最小、这个s集(kd树上的) 值都是 当前点的x、y坐标 }int dis(int now){int lin=0;    for(int i=0;i<2;i++)lin+=max(s[now].xiao[i]-q.xy[i],0);for(int i=0;i<2;i++)lin+=max(q.xy[i]-s[now].da[i],0);return lin;//这块比较难理解,如果第一个循环>0第二个循环就一定为0  反之亦然   所以它实际上算的是点q到 now点对应的矩形的 曼哈顿距离 }void build(int &k,int l,int r,int xydo)//建kd树   k值要返回,因为没有初值   xydo表示当前比较的什么坐标  0是x 1是y {k=(l+r)>>1;   xycmp=xydo;   //用k作为编号方便(依次标也没人管你,这不是线段树,可以乱),   xycmp是比较的坐标 nth_element(d+l,d+k,d+r+1,cmp);  //这几乎是为kd树量身打造的函数,详情自行百度或见我 stl 算法总结 add(k,d[k]);   //加入这个中间点 if(l<k)build(xia[k][0],l,k-1,xydo^1); //建左子树 if(r>k)build(xia[k][1],k+1,r,xydo^1); //建右子数 upd(k);         //维护矩形 }   void ins(int k,int xydo)   //插入点   k是当前已有点的编号     {if(q.xy[xydo]<s[k].xy[xydo])   //因为小的在左子树  大的在右子树 {if(xia[k][0])ins(xia[k][0],xydo^1);else xia[k][0]=++n,add(n,q);//没有的话就找到了归宿   加一个 }else{if(xia[k][1])ins(xia[k][1],xydo^1);     //else xia[k][1]=++n,add(n,q);                // 同上 }upd(k);  //不要忘了更新 }void zhao(int k){ans=min(ans,(abs(q.xy[0]-s[k].xy[0])+abs(q.xy[1]-s[k].xy[1])));//答案取这个点和要找点的最小距离 int ld=(xia[k][0])?dis(xia[k][0]):inf;//如果在矩形内部就是0,在外部就是最小距离,没有这个子节点就是inf int rd=(xia[k][1])?dis(xia[k][1]):inf;if(ld<rd){if(ld<ans)zhao(xia[k][0]);if(rd<ans)zhao(xia[k][1]);//用访问顺序来优化(优先访问距离短的来更新答案,这样长的就有可能被卡掉) }else{  if(rd<ans)zhao(xia[k][1]);if(ld<ans)zhao(xia[k][0]);}}
}kd;
int main()
{scanf("%d%d",&n,&m);for(i=1;i<=n;i++){scanf("%d%d",&d[i].xy[0],&d[i].xy[1]);        }kd.build(rt,1,n,0);for(int i=1;i<=m;i++){scanf("%d%d%d",&op,&kd.q.xy[0],&kd.q.xy[1]);if(op==1){kd.ins(rt,0);}else{ans=inf;kd.zhao(rt);printf("%d\n",ans);  }}return 0;} 

2017.3.25 SJY摆石子 思考记录相关推荐

  1. 2017.3.25 魔术球问题 思考记录

    这个题还是不难的..(想了20分钟就出完解) 二分+网络流检验,,能加在上面的数大的向小的连边 总点数-最大匹配>n    :{l=mid+1,      记录答案       } else   ...

  2. 2017.10.5 最短母串 思考记录

    这个题n<=15,可以用10表示选取情况下的最优值 预处理两个串之间的连接关系,然后枚举状态转移 然而这个题还要输出方案,,而且还不让你开空间. 所以只能记录前继动态判断.. 所以十分难写难调 ...

  3. 2017.9.26 块的计数 思考记录

    这种题就属于那种描述很简单,要求很简单,但就是无从下手的题 这个题我只有n根n做法..枚举因数检验.. 首先对于任何块的大小,方案唯一,这是显然的,,如果划分位置改变1,一定有一个位置+1,一个位置- ...

  4. 2017.8.8 魔兽地图DotR 思考记录

    假题害人..  明明说了是一棵树,却还要强行加一组坑爹数据   所以网上的题解挂了好多 这题是很综合的树上背包问题. 由依赖关系转化为一些枚举来跑多重背包 由于是 "一棵树" 所以 ...

  5. 2017 9 25翁凯html学习记录

    今天js高级程序设计一书到货,正式开学学习web前端. 1.html文件框架 <html></html>之间的为html代码 <head></head> ...

  6. 2017.10.23 chess 中国象棋 思考记录

    这种题的一般解法: 1. 发现状压可以搞,然后发现状态爆炸 2.考虑状态特点,一共只有几种可能的状态 3.考虑可不可以只对状态进行计数 4.离散统计贡献 码: #include<iostream ...

  7. 2017.10.19 起床困难综合征 思考记录

    2333noi送分题 首先暴力试每个数有些二进制位是会重复算的,,所以就考虑能否把每个二进制位独立考虑 老性质:二进制运算每一位独立 所以二进制dp,如果这一位输入1,是多少,输入0,是多少 然后按二 ...

  8. 2017.10.11 network 网络扩容 思考记录

    第一问是网络流. 第二问是费用流,但之前的边依然是可以用的,所以每个点决策:用原来的流量    购买一条流量,扫每条边加进去就可以了 然后限制流出为k 码: #include<iostream& ...

  9. 2017.10.7 弹飞绵羊 思考记录

    ..这个题根据弹后的关系是很容易想出一个森林的..修改连接关系就是cut和link.. 但是分块的做法似乎十分优越,,好写好调.所以学一下分块的写法 首先每一个区间的信息都是可以做到O(1)查询的.. ...

最新文章

  1. topcoder srm 330 div1
  2. 灰度不变性LBP( gray scale invariant) 旋转不变性LBP(rotation invariant)旋转不变等价LBP(rotation uniform invarian )
  3. ionic 实用技巧
  4. 成功解决没有tf.nn.rnn_cell属性
  5. nginx访问502 gateway,*1 connect() failed (111: Connection refused) while connecting to upstream
  6. php镂空窗,木窗镂空的雕刻象征着什么?黑色在彝族人民心中有何寓意?陆川猪为何是著名“陆川三宝”之一?...
  7. Tr A 矩阵快速幂
  8. 只懂 Git 就能成为架构专家?这得从代码的物理分析说起
  9. Android系统Camera录像过程分析
  10. php get安全过滤,php 有效安全过滤get,posd,cookie_PHP教程
  11. 人脸数据库收集——深度学习
  12. 外汇套利原理及策略EA
  13. 全国省市区的数据导入
  14. 记服务器遭遇ssh攻击及应对过程
  15. 如何理解零知识 zkSNARK应用中的Nullifier Hash攻击?
  16. 微信小游戏获取排行榜
  17. 语音验证码接口对接DEMO示例PHP语言
  18. pandas文件保存操作
  19. CSS -- CSS字体样式、文本样式、去掉列表的小圆点、背景、背景渐变
  20. 神奇的H5视频画中画功能

热门文章

  1. Android笔记 style样式
  2. 三分钟让面试官满意系列 - Bagging和Boosting 的联系及区别
  3. simulink接收串口数据_JLink RTT连接Simulink
  4. Mac上Java开发环境配置
  5. Java输入n个无序的整数,请编写程序,找出其中最大数所在的位置.请以以下三种情况运行你的程序.以便验证你的程序是否正确.(不得少于5个数)① 最大数在最前 ② 最大数在最后 ③ 最大
  6. vue data为什么是函数_由 Vue 中三个常见问题引发的深度思考
  7. python抽奖程序_Python编写抽奖式随机提问程序
  8. 一建管道工程122知识点_背诵的知识点是否边缘化?一建市政一本通+学霸笔记,教你只记重点...
  9. Python练习:平方值格式化
  10. cleanmymac 4.2_市委刚刚批准:11月1号立即执行! 农业银行存款利率4.2%,1万元存1年,有多少利息?...