【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 ...
随机推荐
- Ubuntu终端命令行不显示颜色
在网上找到的一个有效方案是在.bash_profile 中增加颜色定义 export LS_COLORS='di=01;35:ln=01;36:pi=40;33:so=01;35:do=01;35:b ...
- PAT 1030. 完美数列(25)
给定一个正整数数列,和正整数p,设这个数列中的最大值是M,最小值是m,如果M <= m * p,则称这个数列是完美数列. 现在给定参数p和一些正整数,请你从中选择尽可能多的数构成一个完美数列. ...
- 设置apache https服务
配置http.conf,所在位置d:\wamp\bin\apache\apache2.4.9\conf\http.conf LoadModule socache_shmcb_module modu ...
- 关于code reiview
先谈谈三个code review的关键因素: 一.创建review要简单 code reivew是一个程序员日常工作中经常做的一件事,理论上来讲,任何一个将要submit到SCM的change,都必须 ...
- TextBox自定义控件
首先来一发图: 今天主要说的textBox内部给予提示: 使用自定义控件方式:TextBoxTip继承TextBox 利用TextBox的背景画刷功能 VisualBrush是一种比较特殊的笔刷,它的 ...
- 熟悉css/css3颜色属性
颜色属性无处不在.字体要用颜色,背景可以有颜色,粒子特效更是离不开颜色.本文参考了一些资料简单总结下以备日后查阅. css中颜色的定义方式: 十六进制色 RGB & RGBA HSL & ...
- AndFix热修复 —— 实战与源码解析
当你的应用发布后第二天却发现一个重要的bug要修复,头疼的同时你可能想着赶紧修复重新打个包发布出去,让用户收到自动更新重新下载.但是万事皆有可能,万一隔一天又发现一个急需修复的bug呢?难道再次发布打 ...
- HTML5+JS 《五子飞》游戏实现(六)鼠标响应与多重选择
上一章我们提到了如果有多条线上的棋子可以被吃掉,那么游戏需要提示用户,让用户选择吃哪条线上的.另外因为是网页游戏,所以一定要实现鼠标单击棋子可以进行操作. 当鼠标移动棋子上面后,切换鼠标指针为手形,移 ...
- 项目分布式部署那些事(2):基于OCS(Memcached)的Session共享方案
在不久之前发布了一篇"项目分布式部署那些事(1):ONS消息队列.基于Redis的Session共享,开源共享",因为一些问题我们使用了阿里云的OCS,下面就来简单的介绍和分享下相 ...
- 新玩具---Amazon Kindle PaperWhite 2
自从将闲置了一段时间的K3 Keyboard 3G送人后,就一直用Nexus7平板上装Kindle程序来读书,用着也挺好,没有出现很多人说的费眼问题,说来也奇怪上学毕业之后,一直从事编程相关的工作有七 ...