看了青岛赛区的题简单学了一下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. C之面向对象编程20170707

    语言只是工具,设计思维才是根本.C虽然是面向过程的语言,但也是可以实现面向对象编程的,本文就是介绍如何使用C语言实现面向对象编程. 我们知道面向对象主要有三大特性:封装,继承,和多态,下面就从这个三个 ...

  2. jquery、css3动态显示百分比圆

    动态显示百分圆 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <m ...

  3. OpenResty初涉

    关于openresty可参考官方文档: http://openresty.org/cn/download.html 1.这个是什么? 在互联网公司,Nginx可以说是标配组件,但是主要场景还是负载均衡 ...

  4. maven私服Nexus3.2的使用

    maven搭建私服的步骤: 分三步: 第一步:下载maven的安装包,然后配置好maven的环境变量. 第二步:将maven的私服Nexus安装好,修改maven的配置文件setting.xml问,在 ...

  5. WIFI Direct(Wi-Fi P2P)

    Wi-Fi Direct技术是Wi-Fi产业链向蓝牙技术发起的挑战,它试图完全取代蓝牙 Wi-Fi Direct是一种点对点连接技术,它可以在两台station之间直接建立tcp/ip链接,并不需要A ...

  6. 单例 ------ C++实现

    基础知识掌握: 单例考虑三点:内存何时释放.运行速度如何.多线程下能否保证只有一个实例 如果获取对象的返回值类型是引用,返回值赋值给变量而不是引用会进行对象的拷贝,这样就会出现两个对象,可以把显示声明 ...

  7. php优秀网摘

    1.thinkphp的目录结构设计经验总结 说明:thinkphp3.2.3对类没有深刻的认识,对项目规模和架构有很糟糕的影响.这里写的目录结构和设计模式相当于对3.2添加了面向对象架构.第二个链接是 ...

  8. Python学习笔记(十五)用Python获取本地数据

    f1 = open(r'E:\Python\Data\data1.txt') #读取data1.txt文件,使用系统默认缓冲区大小, 为了读取快点,使用缓存吧! f = open(r'E:\Pytho ...

  9. 搭建简单的node+express+mongodb项目

    安装 首先要确保已经安装了 Node.js,接下来创建一个目录,然后进入此目录并将其作为当前工作目录. mkdir myapp cd myapp 通过 npm init 命令为应用创建一个 packa ...

  10. Use JPath but not recursively loop a JObject to modify the values.

    I am dealing with a Json file, I parsed it into jObject, I have another list which flattened the pro ...