看了青岛赛区的题简单学了一下kd,感觉这东西还是挺厉害的

一般kd树找最近点对最坏是O(n),但是随机情况下跑得还是很快的

kd树是一棵BST,但是每一层的关键字不同

一般写法是按照每一维轮流来,这一维小的放左子树,大的放右边的

每个节点再维护这节点所管辖的节点每一维的范围,这样基本就能做题了

kdtree一般是静态直接建好的,插入可以套一个替罪羊树重构做到logn,但是据说慢

那么怎么查询最近点呢

每到一个节点,比较通过这节点所管辖点的每一维的范围,估计出可能最小的距离

优先访问估值优的子树

可以看到查询几乎就是个搜索+剪枝,所以最坏是O(n),最远点类似

这样bzoj1941就解了

 #include<bits/stdc++.h>

 using namespace std;
const int inf=1e9+;
int key,dmx,dmi,root,n,x[],y[]; struct node
{
int son[],mi[],mx[],d[];
friend bool operator <(node a,node b)
{
return a.d[key]<b.d[key];
}
friend int dis(node a,node b)
{
return abs(a.d[]-b.d[])+abs(a.d[]-b.d[]);
}
} po; struct kdtree
{
node a[];
void init()
{
a[].son[]=a[].son[]=;
for (int i=; i<; i++)
{
a[].mi[i]=inf;
a[].mx[i]=-inf;
}
}
void update(int x)
{
int l=a[x].son[],r=a[x].son[];
for (int i=; i<; i++)
{
a[x].mi[i]=min(a[x].d[i],min(a[l].mi[i],a[r].mi[i]));
a[x].mx[i]=max(a[x].d[i],max(a[l].mx[i],a[r].mx[i]));
}
}
int build(int l,int r,int cur)
{
if (l>r) return ;
int m=(l+r)>>;
key=cur; nth_element(a+l,a+m,a+r+);
a[m].son[]=build(l,m-,cur^);
a[m].son[]=build(m+,r,cur^);
update(m);
return m;
}
int getmi(int x)
{
int s=;
for (int i=;i<;i++)
s+=max(po.d[i]-a[x].mx[i],)+max(a[x].mi[i]-po.d[i],);
return s;
}
int getmx(int x)
{
int s=;
for (int i=;i<;i++)
s+=max(abs(po.d[i]-a[x].mi[i]),abs(po.d[i]-a[x].mx[i]));
return s;
}
void askmx(int q)
{
dmx=max(dmx,dis(a[q],po));
int l=a[q].son[],r=a[q].son[],dl=-inf,dr=-inf;
if (l) dl=getmx(l);
if (r) dr=getmx(r);
if (dl>dr)
{
if (dl>dmx) askmx(l);
if (dr>dmx) askmx(r);
}
else {
if (dr>dmx) askmx(r);
if (dl>dmx) askmx(l);
}
}
void askmi(int q)
{
int dd=dis(a[q],po); if (dd) dmi=min(dmi,dd);
int l=a[q].son[],r=a[q].son[],dl=inf,dr=inf;
if (l) dl=getmi(l);
if (r) dr=getmi(r);
if (dl<dr)
{
if (dl<dmi) askmi(l);
if (dr<dmi) askmi(r);
}
else {
if (dr<dmi) askmi(r);
if (dl<dmi) askmi(l);
}
}
} kd; int main()
{
kd.init();
scanf("%d",&n);
for (int i=; i<=n; i++)
{
scanf("%d%d",&x[i],&y[i]);
kd.a[i].d[]=x[i];
kd.a[i].d[]=y[i];
}
root=kd.build(,n,); int ans=inf;
for (int i=;i<=n;i++)
{
dmx=-inf,dmi=inf;
po.d[]=x[i],po.d[]=y[i];
kd.askmx(root); kd.askmi(root);
ans=min(ans,dmx-dmi);
}
printf("%d\n",ans);
}

bzoj1941

hdu5992要加一维价格剪枝,如果这个节点所辖节点的最小价格都比询问大就不访问了

 #include<bits/stdc++.h>

 using namespace std;
typedef long long ll;
const int inf=1e9+;
int key,root,n,m;
ll len;
ll sqr(ll x)
{
return x*x;
} struct node
{
int d[],mi[],mx[],son[],id;
friend bool operator <(node a,node b)
{
return a.d[key]<b.d[key];
}
friend ll dis(node a,node b)
{
return sqr(a.d[]-b.d[])+sqr(a.d[]-b.d[]);
}
} po,ans; struct kdtree
{
node a[];
void init()
{
a[].son[]=a[].son[]=;
for (int i=; i<; i++)
{
a[].mi[i]=inf;
a[].mx[i]=-inf;
}
}
void update(int x)
{
int l=a[x].son[],r=a[x].son[];
for (int i=; i<; i++)
{
a[x].mi[i]=min(a[x].d[i],min(a[l].mi[i],a[r].mi[i]));
a[x].mx[i]=max(a[x].d[i],max(a[l].mx[i],a[r].mx[i]));
}
}
int build(int l,int r,int cur)
{
if (l>r) return ;
int m=(l+r)>>;
key=cur; nth_element(a+l,a+m,a+r+);
a[m].son[]=build(l,m-,cur^);
a[m].son[]=build(m+,r,cur^);
update(m);
return m;
}
void check(int q)
{
if (a[q].d[]>po.d[]) return;
ll l=dis(a[q],po);
if ((len>l)||((len==l)&&ans.id>a[q].id))
{
ans=a[q];
len=l;
}
}
ll get(int q)
{
if (!q||a[q].mi[]>po.d[]) return 1e18+;
ll s=;
for (int i=; i<; i++)
{
if (po.d[i]<a[q].mi[i]) s+=sqr(po.d[i]-a[q].mi[i]);
if (po.d[i]>a[q].mx[i]) s+=sqr(po.d[i]-a[q].mx[i]);
}
return s;
}
void ask(int q)
{
if (a[q].mi[]>po.d[]) return;
check(q);
int l=a[q].son[],r=a[q].son[];
ll dl=get(l),dr=get(r);
if (dl<dr)
{
if (dl<=len) ask(l);
if (dr<=len) ask(r);
}
else {
if (dr<=len) ask(r);
if (dl<=len) ask(l);
}
}
} kd; int main()
{
kd.init();
int cas;
scanf("%d",&cas);
while (cas--)
{
scanf("%d%d",&n,&m);
for (int i=; i<=n; i++)
{
int x,y,c;
scanf("%d%d%d",&x,&y,&c);
kd.a[i].d[]=x; kd.a[i].d[]=y; kd.a[i].d[]=c;
kd.a[i].id=i;
}
root=kd.build(,n,);
for (int i=; i<=m; i++)
{
scanf("%d%d%d",&po.d[],&po.d[],&po.d[]);
len=1e18; kd.ask(root);
printf("%d %d %d\n",ans.d[],ans.d[],ans.d[]);
}
}
}

hdu5992

bzoj1941 hdu5992的更多相关文章

  1. 【bzoj1941】 Sdoi2010—Hide and Seek

    http://www.lydsy.com/JudgeOnline/problem.php?id=1941 (题目链接) 题意 给出n个二维平面上的点,求一点使到最远点的距离-最近点的距离最小. Sol ...

  2. 【kd-tree】bzoj1941 [Sdoi2010]Hide and Seek

    枚举每个点,计算离他最近的和最远的点. #include<cstdio> #include<cmath> #include<algorithm> using nam ...

  3. [BZOJ1941][Sdoi2010]Hide and Seek

    [BZOJ1941][Sdoi2010]Hide and Seek 试题描述 小猪iPig在PKU刚上完了无聊的猪性代数课,天资聪慧的iPig被这门对他来说无比简单的课弄得非常寂寞,为了消除寂寞感,他 ...

  4. 【BZOJ1941】Hide and Seek(KD-Tree)

    [BZOJ1941]Hide and Seek(KD-Tree) 题面 BZOJ 洛谷 题解 \(KD-Tree\)对于每个点搜一下最近点和最远点就好了 #include<iostream> ...

  5. 【BZOJ1941】[Sdoi2010]Hide and Seek KDtree

    [BZOJ1941][Sdoi2010]Hide and Seek Description 小猪iPig在PKU刚上完了无聊的猪性代数课,天资聪慧的iPig被这门对他来说无比简单的课弄得非常寂寞,为了 ...

  6. KD-Tree复习笔记(BZOJ1941 & BZOJ2648 & BZOJ4066)

    快一年了都没碰到什么必须用KDT的题目导致模板完全忘光了,重新复习了一下. K_Dimention_Tree是一种用来处理二维以上问题的数据结构(OI中一般都是二维),本质是二维启发式估价函数实现剪枝 ...

  7. [bzoj1941][Sdoi2010]Hide and Seek_KD-Tree

    Hide and Seek bzoj-1941 Sdoi-2010 题目大意:给出平面上n个点,选出一个点,使得距离这个点的最远点曼哈顿距离减去距离这个点的最近非己点的曼哈顿距离最小.输出最小曼哈顿距 ...

  8. hdu-5992 Finding Hotels(kd-tree)

    题目链接: Finding Hotels Time Limit: 2000/1000 MS (Java/Others)     Memory Limit: 102400/102400 K (Java/ ...

  9. 【BZOJ-1941】Hide and Seek KD-Tree

    1941: [Sdoi2010]Hide and Seek Time Limit: 16 Sec  Memory Limit: 162 MBSubmit: 830  Solved: 455[Submi ...

随机推荐

  1. 在github fork的项目中推送与抓取

    github -- fork提交项目:自己的仓库和原仓库进行Git同步的操作. 1. 获取你fork的原仓库的更新过的最新代码:如果没有远程原始分支则需要增加. git remote add upst ...

  2. OpenCV---对象测量

    一:获取图像的外接矩形boundingRect和几何距moments import cv2 as cv import numpy as np def measure_object(image): gr ...

  3. package.json文档

    之前在博客中写过一篇关于 " node.js的安装配置 " 的文章,里面有提到利用 gulp watch 来监听文档的变化.其中需要 package.json 文件才能实现效果,所 ...

  4. LightOJ 1364 树形DP

    52张扑克牌,问拿到指定数量的4个花色的最少次数期望是多少,其中拿到joker必须马上将其视作一种花色,且要使后续期望最小. 转移很容易想到,主要是两张joker的处理,一个状态除了普通的4个方向的转 ...

  5. FTP、SFTP文件下载内容校验

    描述: 从FTP.SFTP下载的文件做MD5码校验,文件名和MD5码值存放在表格里,表格位置在FTP.SFTP服务器上. os模块只能遍历本地目录/文件,需要先连接FTP.SFTP服务器,将表格下载到 ...

  6. CSS预处理器们

    CSS预处理器有很多,最早的是2006年的Less,到后来2010年的SASS,还有现在也很出名的Stylus.不过要使用它们都要使用一些工具,比如Less的话要使用Grunt或者Gulp或者Node ...

  7. Goolge-Guava Concurrent中的Service

    最近在学习了下Google的Guava包,发现这真是一个好东西啊..由于平时也会写一些基于多线程的东西,所以特意了解了下这个Service框架.这里Guava包里的Service接口用于封装一个服务对 ...

  8. 谨慎重载clone方法

    本文涉及到的概念 1.浅拷贝和深拷贝 2..clone方法的作用和使用方式 3.拷贝构造器和拷贝工厂   1.浅拷贝和深拷贝 浅拷贝 一个类实现Cloneable接口,然后,该类的实例调用clone方 ...

  9. javaScript基础语法介绍

    简介 JavaScript是一种脚本语言. (脚本,一条条的文字命令.执行时由系统的一个解释器,将其一条条的翻译成机器可识别的指令,然后执行.常见的脚本:批处理脚本.T-SQL脚本.VBScript等 ...

  10. 2016CCPC东北地区大学生程序设计竞赛 (2018年8月22日组队训练赛)

    题目链接:http://acm.hdu.edu.cn/search.php?field=problem&key=2016CCPC%B6%AB%B1%B1%B5%D8%C7%F8%B4%F3%D ...