【BZOJ-4520】K远点对 KD-Tree + 堆
4520: [Cqoi2016]K远点对
Time Limit: 30 Sec Memory Limit: 512 MB
Submit: 490 Solved: 237
[Submit][Status][Discuss]
Description
已知平面内 N 个点的坐标,求欧氏距离下的第 K 远点对。
Input
Output
输出文件第一行为一个整数,表示第 K 远点对的距离的平方(一定是个整数)。
Sample Input
0 0
0 1
1 0
1 1
2 0
2 1
1 2
0 2
3 0
3 1
Sample Output
HINT
Source
Solution
正解似乎是维护凸包!@#%……
不过KD Tree暴力搞就可以了,而且实测效率很高
具体的做法就是:先将平面上的所有点加入KDTree中,然后维护一个小根堆,枚举每个点进行询问
小根堆的用途及相当于当前最优解为小根堆的堆顶
Attention:
有些点会被计算两次,所以堆中实际是2*k个元素
注意开longlong,极限值的取值
Code
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<cstdlib>
using namespace std;
long long read()
{
long long x=,f=; char ch=getchar();
while (ch<'' || ch>'') {if (ch=='-') f=-; ch=getchar();}
while (ch>='' && ch<='') {x=x*+ch-''; ch=getchar();}
return x*f;
}
#define maxn 100010
#define inf 100000000000000000LL
int n,k,D;
long long sqr(long long a) {return (long long)(a*a);}
struct PointNode
{
int l,r; long long d[],maxx[],minn[];
bool operator < (const PointNode & A) const {return d[D]<A.d[D];}
PointNode (long long x=,long long y=) {l=r=; d[]=x; d[]=y;}
}p[maxn];
priority_queue<long long, vector<long long>, greater<long long> > heap;
long long dis(PointNode A,PointNode B) {return sqr(A.d[]-B.d[])+sqr(A.d[]-B.d[]);}
struct KDTreeNode
{
int rt;
PointNode Point,tree[maxn<<];
void Update(int now)
{
for (int i=; i<=; i++)
{
tree[now].minn[i]=tree[now].maxx[i]=tree[now].d[i];
if (tree[now].l)
tree[now].minn[i]=min(tree[tree[now].l].minn[i],tree[now].minn[i]),tree[now].maxx[i]=max(tree[tree[now].l].maxx[i],tree[now].maxx[i]);
if (tree[now].r)
tree[now].minn[i]=min(tree[tree[now].r].minn[i],tree[now].minn[i]),tree[now].maxx[i]=max(tree[tree[now].r].maxx[i],tree[now].maxx[i]);
}
}
int BuildTree(int l,int r,int dd)
{
int mid=(l+r)>>;
D=dd; nth_element(p+l,p+mid,p+r+);
tree[mid]=p[mid];
for (int i=; i<=; i++) tree[mid].minn[i]=tree[mid].maxx[i]=tree[mid].d[i];
if (l<mid) tree[mid].l=BuildTree(l,mid-,dd^);
if (r>mid) tree[mid].r=BuildTree(mid+,r,dd^);
Update(mid);
return mid;
}
long long dist(int pl,PointNode P)
{
long long re=;
for (int i=; i<=; i++)
re+=max(sqr(P.d[i]-tree[pl].minn[i]),sqr(P.d[i]-tree[pl].maxx[i]));
return re;
}
void Query(int now)
{
long long dl,dr,d0;
d0=dis(tree[now],Point);
if (d0>heap.top()) heap.pop(),heap.push(d0);
if (tree[now].l) dl=dist(tree[now].l,Point); else dl=-inf;
if (tree[now].r) dr=dist(tree[now].r,Point); else dr=-inf;
if (dl>dr)
{
if (dl>heap.top()) Query(tree[now].l);
if (dr>heap.top()) Query(tree[now].r);
}
else
{
if (dr>heap.top()) Query(tree[now].r);
if (dl>heap.top()) Query(tree[now].l);
}
}
}KDTree;
int main()
{
// freopen("farthest.in","r",stdin);
// freopen("farthest.out","w",stdout);
n=read(); k=read();
for (int x,y,i=; i<=n; i++) x=read(),y=read(),p[i]=PointNode(x,y);
KDTree.rt=KDTree.BuildTree(,n,);
for (int i=; i<=k+k; i++) heap.push(0LL);
for (int i=; i<=n; i++)
KDTree.Point=p[i],KDTree.Query(KDTree.rt);
printf("%lld\n",heap.top());
return ;
}
【BZOJ-4520】K远点对 KD-Tree + 堆的更多相关文章
- BZOJ 4520: [Cqoi2016]K远点对(k-d tree)
Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 1162 Solved: 618[Submit][Status][Discuss] Descripti ...
- BZOJ4520:[CQOI2016]K远点对(K-D Tree)
Description 已知平面内 N 个点的坐标,求欧氏距离下的第 K 远点对. Input 输入文件第一行为用空格隔开的两个整数 N, K.接下来 N 行,每行两个整数 X,Y,表示一个点 的坐标 ...
- BZOJ - 4520 K远点对
题意:已知平面内 N 个点的坐标,求欧氏距离下的第 K 远点对 维护大小为2k最小堆,KD树的估值用前面提到的做法 PS.网上有人估价是使用边界四个点的最值来独立枚举,然而这样写似乎过不了 #incl ...
- BZOJ 3053: The Closest M Points(K-D Tree)
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1235 Solved: 418[Submit][Status][Discuss] Descripti ...
- BZOJ 1941: [Sdoi2010]Hide and Seek(k-d Tree)
Time Limit: 16 Sec Memory Limit: 162 MBSubmit: 1712 Solved: 932[Submit][Status][Discuss] Descripti ...
- BZOJ 3489: A simple rmq problem(K-D Tree)
Time Limit: 40 Sec Memory Limit: 512 MBSubmit: 2579 Solved: 888[Submit][Status][Discuss] Descripti ...
- BZOJ 2648 SJY摆棋子(KD Tree)
http://www.lydsy.com/JudgeOnline/problem.php?id=2648 题意: 思路: KDtree模板题. 参考自http://www.cnblogs.com/ra ...
- BZOJ 4520 [Cqoi2016]K远点对(KD树)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4520 [题目大意] 求K远点对距离 [题解] 修改估价函数为欧式上界估价,对每个点进行 ...
- BZOJ 4520: [Cqoi2016]K远点对
4520: [Cqoi2016]K远点对 Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 638 Solved: 340[Submit][Status ...
- BZOJ 4520: [Cqoi2016]K远点对 KDtree + 估价函数 + 堆
Code: #include<bits/stdc++.h> #define ll long long #define maxn 200000 #define inf 10000000000 ...
随机推荐
- php常见问题
1,新安装的lamp在打开php文件的时候出现access forbid问题,这个出现的原因是directory的路径权限问题,解决方法 将httpd.conf中的 <Directory /&g ...
- MySQL数据库集群进行正确配置步骤
MySQL数据库集群进行正确配置步骤 2010-06-09 10:47 arrowcat 博客园 字号:T | T 我们今天是要和大家一起分享的是对MySQL数据库集群进行正确配置,我前两天在相关网站 ...
- DEDECMS之九 文章采集
到很多网友都为织梦(DEDECMS)的采集教程头疼,的确,官方出的教程太笼统了,什么都没说,换个网站你什么都做不了,这个教程是最详尽的教程,让你一看即会! 一.列表采集 第一步.我们打开织梦后台点击采 ...
- 投入Html5的怀抱,最近在研究的Egret
html5没有办法不关注,实在太火热了,几年前还不行,如今确是环境较好,typescript语言很好学习,可能基于之前的基础,不到一个星期就基本上差不多了,虽然还有一些小问题,但那都是经验积累下来可以 ...
- C#/JS 获取二维数组组合
C#获取二维数组组合 using System; using System.Collections.Generic; using System.Linq; using System.Text; usi ...
- indows 8上强制Visual Studio以管理员身份运行
http://diaosbook.com/Post/2013/2/28/force-visual-studio-always-run-as-admin-on-windows-8 Windows 8的一 ...
- linux ISO/IMG make
sudo dd if=/PATH/*.ISO of=/dev/sdb 1.制作启动U盘需要sdb,不能sdb1,否则会提示isolinux.bin文件丢失 2.TF卡,设置sdb1?忘了 /* sy ...
- 利用performance属性查看网页性能
一般我们可以通过浏览器的调试工具-网络面板,或者代理工具查看网页加载过程中的各个阶段的耗时.而利用window.performance属性则可以获得更为精确的原始数据,以毫秒为单位,精确到微秒. pe ...
- 手把手教你使用markdown
这是 [认真学编程] 系列的 第3篇 文章,欢迎点赞分享.写留言,这些都是对我最好的支持. 全文2300字,阅读预计5分钟] 在前面几篇文章中,多次提到装X神器markdown,本人也是markdow ...
- java中String、StringBuffer、StringBuilder的区别
java中String.StringBuffer.StringBuilder是编程中经常使用的字符串类,他们之间的区别也是经常在面试中会问到的问题.现在总结一下,看看他们的不同与相同. 1.可变与不可 ...