bzoj1941 hdu5992
看了青岛赛区的题简单学了一下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的更多相关文章
- 【bzoj1941】 Sdoi2010—Hide and Seek
http://www.lydsy.com/JudgeOnline/problem.php?id=1941 (题目链接) 题意 给出n个二维平面上的点,求一点使到最远点的距离-最近点的距离最小. Sol ...
- 【kd-tree】bzoj1941 [Sdoi2010]Hide and Seek
枚举每个点,计算离他最近的和最远的点. #include<cstdio> #include<cmath> #include<algorithm> using nam ...
- [BZOJ1941][Sdoi2010]Hide and Seek
[BZOJ1941][Sdoi2010]Hide and Seek 试题描述 小猪iPig在PKU刚上完了无聊的猪性代数课,天资聪慧的iPig被这门对他来说无比简单的课弄得非常寂寞,为了消除寂寞感,他 ...
- 【BZOJ1941】Hide and Seek(KD-Tree)
[BZOJ1941]Hide and Seek(KD-Tree) 题面 BZOJ 洛谷 题解 \(KD-Tree\)对于每个点搜一下最近点和最远点就好了 #include<iostream> ...
- 【BZOJ1941】[Sdoi2010]Hide and Seek KDtree
[BZOJ1941][Sdoi2010]Hide and Seek Description 小猪iPig在PKU刚上完了无聊的猪性代数课,天资聪慧的iPig被这门对他来说无比简单的课弄得非常寂寞,为了 ...
- KD-Tree复习笔记(BZOJ1941 & BZOJ2648 & BZOJ4066)
快一年了都没碰到什么必须用KDT的题目导致模板完全忘光了,重新复习了一下. K_Dimention_Tree是一种用来处理二维以上问题的数据结构(OI中一般都是二维),本质是二维启发式估价函数实现剪枝 ...
- [bzoj1941][Sdoi2010]Hide and Seek_KD-Tree
Hide and Seek bzoj-1941 Sdoi-2010 题目大意:给出平面上n个点,选出一个点,使得距离这个点的最远点曼哈顿距离减去距离这个点的最近非己点的曼哈顿距离最小.输出最小曼哈顿距 ...
- hdu-5992 Finding Hotels(kd-tree)
题目链接: Finding Hotels Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 102400/102400 K (Java/ ...
- 【BZOJ-1941】Hide and Seek KD-Tree
1941: [Sdoi2010]Hide and Seek Time Limit: 16 Sec Memory Limit: 162 MBSubmit: 830 Solved: 455[Submi ...
随机推荐
- Python之数据库导入(py3.5)
数据库版本:MySQL Python版本:3.5 之前用想用MySQLdb来着,后来发现py3.5版本不支持,现选择pymysql 现在想将数据库adidas中的表jd_comment读取至pytho ...
- php整理
linux上安装php配套环境有些繁琐 推荐使用一键安装: https://lnmp.org/install.html phalcon框架环境: centos7下php7.0.x安装phalcon框架
- python基础之装饰器(实例)
1.必备 #### 第一波 #### def foo(): print 'foo' foo #表示是函数 foo() #表示执行foo函数 #### 第二波 #### def foo(): print ...
- 深入分析Java中的 == 和equals
关于Java中的 == 和equals的解释请看这位博主的文章 :http://www.cnblogs.com/dolphin0520/p/3592500.html 以下是我对这篇文章的一些扩展. 对 ...
- VisualSVN 5.1.4破解
1. 备份visualSVNbin目录 2. 打开VS命令提示工具,反编译VisualSVN.Core.L.dll 运行命令 ildasam "VisualSVN安装目录\bin\Visua ...
- libuv移植到ios
libuv官网只提供了os x的编译方法,没有IOS的.既然os x和ios的系统内核差不多,并且编译工具都是xcode,那我们只要重新指定cpu架构,就可以编译出ios版的了. 1.安装python ...
- 【VSCode】Windows下VSCode编译调试c/c++【更新 2018.03.27】
--------– 2018.03.27 更新--------- 便携版已更新,点此获取便携版 已知BUG:中文目录无法正常调试 用于cpptools 0.15.0插件的配置文件更新 新的launch ...
- hdu 4940 Destroy Transportation system (无源汇上下界可行流)
Destroy Transportation system Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 ...
- BZOJ做题记录[0512~?]
觉得做一道开一篇真不好...好多想找的东西都被刷下去了... 至于?的日期究竟到什么时候...还是看心情...但是估计不会超过七天吧 最后更新时间:05/19 10:42 [05/14 10:56]我 ...
- 【BZOJ】2120: 数颜色 带修改的莫队算法
[题意]给定n个数字,m次操作,每次询问区间不同数字的个数,或修改某个位置的数字.n,m<=10^4,ai<=10^6. [算法]带修改的莫队算法 [题解]对于询问(x,y,t),其中t是 ...