2017.3.25 SJY摆石子 思考记录
终于找到了一个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摆石子 思考记录相关推荐
- 2017.3.25 魔术球问题 思考记录
这个题还是不难的..(想了20分钟就出完解) 二分+网络流检验,,能加在上面的数大的向小的连边 总点数-最大匹配>n :{l=mid+1, 记录答案 } else ...
- 2017.10.5 最短母串 思考记录
这个题n<=15,可以用10表示选取情况下的最优值 预处理两个串之间的连接关系,然后枚举状态转移 然而这个题还要输出方案,,而且还不让你开空间. 所以只能记录前继动态判断.. 所以十分难写难调 ...
- 2017.9.26 块的计数 思考记录
这种题就属于那种描述很简单,要求很简单,但就是无从下手的题 这个题我只有n根n做法..枚举因数检验.. 首先对于任何块的大小,方案唯一,这是显然的,,如果划分位置改变1,一定有一个位置+1,一个位置- ...
- 2017.8.8 魔兽地图DotR 思考记录
假题害人.. 明明说了是一棵树,却还要强行加一组坑爹数据 所以网上的题解挂了好多 这题是很综合的树上背包问题. 由依赖关系转化为一些枚举来跑多重背包 由于是 "一棵树" 所以 ...
- 2017 9 25翁凯html学习记录
今天js高级程序设计一书到货,正式开学学习web前端. 1.html文件框架 <html></html>之间的为html代码 <head></head> ...
- 2017.10.23 chess 中国象棋 思考记录
这种题的一般解法: 1. 发现状压可以搞,然后发现状态爆炸 2.考虑状态特点,一共只有几种可能的状态 3.考虑可不可以只对状态进行计数 4.离散统计贡献 码: #include<iostream ...
- 2017.10.19 起床困难综合征 思考记录
2333noi送分题 首先暴力试每个数有些二进制位是会重复算的,,所以就考虑能否把每个二进制位独立考虑 老性质:二进制运算每一位独立 所以二进制dp,如果这一位输入1,是多少,输入0,是多少 然后按二 ...
- 2017.10.11 network 网络扩容 思考记录
第一问是网络流. 第二问是费用流,但之前的边依然是可以用的,所以每个点决策:用原来的流量 购买一条流量,扫每条边加进去就可以了 然后限制流出为k 码: #include<iostream& ...
- 2017.10.7 弹飞绵羊 思考记录
..这个题根据弹后的关系是很容易想出一个森林的..修改连接关系就是cut和link.. 但是分块的做法似乎十分优越,,好写好调.所以学一下分块的写法 首先每一个区间的信息都是可以做到O(1)查询的.. ...
最新文章
- topcoder srm 330 div1
- 灰度不变性LBP( gray scale invariant) 旋转不变性LBP(rotation invariant)旋转不变等价LBP(rotation uniform invarian )
- ionic 实用技巧
- 成功解决没有tf.nn.rnn_cell属性
- nginx访问502 gateway,*1 connect() failed (111: Connection refused) while connecting to upstream
- php镂空窗,木窗镂空的雕刻象征着什么?黑色在彝族人民心中有何寓意?陆川猪为何是著名“陆川三宝”之一?...
- Tr A 矩阵快速幂
- 只懂 Git 就能成为架构专家?这得从代码的物理分析说起
- Android系统Camera录像过程分析
- php get安全过滤,php 有效安全过滤get,posd,cookie_PHP教程
- 人脸数据库收集——深度学习
- 外汇套利原理及策略EA
- 全国省市区的数据导入
- 记服务器遭遇ssh攻击及应对过程
- 如何理解零知识 zkSNARK应用中的Nullifier Hash攻击?
- 微信小游戏获取排行榜
- 语音验证码接口对接DEMO示例PHP语言
- pandas文件保存操作
- CSS -- CSS字体样式、文本样式、去掉列表的小圆点、背景、背景渐变
- 神奇的H5视频画中画功能
热门文章
- Android笔记 style样式
- 三分钟让面试官满意系列 - Bagging和Boosting 的联系及区别
- simulink接收串口数据_JLink RTT连接Simulink
- Mac上Java开发环境配置
- Java输入n个无序的整数,请编写程序,找出其中最大数所在的位置.请以以下三种情况运行你的程序.以便验证你的程序是否正确.(不得少于5个数)① 最大数在最前 ② 最大数在最后 ③ 最大
- vue data为什么是函数_由 Vue 中三个常见问题引发的深度思考
- python抽奖程序_Python编写抽奖式随机提问程序
- 一建管道工程122知识点_背诵的知识点是否边缘化?一建市政一本通+学霸笔记,教你只记重点...
- Python练习:平方值格式化
- cleanmymac 4.2_市委刚刚批准:11月1号立即执行! 农业银行存款利率4.2%,1万元存1年,有多少利息?...