【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 ...
随机推荐
- String PK StringBuilder,传说就是传说,只有动手实验,才能得出确定的答案
本机测试结果如下: 大部分情况下,string 性能并不比StringBuilder差,只有特殊情况才出现差异,并非 如前面有些朋友测试的结果哪样,只要使用StringBuilder 就一定比Stri ...
- Linux 网络编程详解二(socket创建流程、多进程版)
netstat -na | grep " --查看TCP/IP协议连接状态 //socket编程提高版--服务器 #include <stdio.h> #include < ...
- swift——启动页国际化:一步一步动态加载启动页图片,启动的时候加载文字
由于公司的需求,要求做一个国际化的启动页,因为app我也弄国际化了,就剩下启动页国际化未完成,百度了呵谷歌了好多答案都不尽如人意,最后也是看见同事完成,我也问了具体的做法,决定分享给需要的人,免得和我 ...
- WPF路径动画(动态逆向动画)
WPF 中的Path.Data 不再多介绍,M开始坐标点 C弧度坐标点 L 直线坐标点 <Path x:Name="path0" Data="M 10,100 C ...
- spring boot/cloud 应用监控
应用的监控功能,对于分布式系统非常重要.如果把分布式系统比作整个社会系统.那么各个服务对应社会中具体服务机构,比如银行.学校.超市等,那么监控就类似于警察局和医院,所以其重要性显而易见.这里说的,监控 ...
- Android开发自学笔记(Android Studio1.3.1)—3.Android应用结构解析
一.R文件是什么? 如上图所示,我们可以通过findViewById方法通过传入R.id.show找到我们的TextView元素,findViewById方法也很好理解,从View中通过Id ...
- 硬件升级win8.1重新安装系统
上次重装系统一年后升级了硬件配置,双11后,再次折腾系统. 配置硬件的选择 部分配件已经升级过了,之前的一直是AMD平台,发热大功耗高,08年我配的AMD 8450+映泰GX790 128M待机在10 ...
- HBase初探
string hbaseCluster = "https://charju.azurehdinsight.net"; string hadoopUsername = "账 ...
- NLPIR分词工具的使用(java环境下)
一.NLPIR是什么? NLPIR(汉语分词系统)由中科大张华平博士团队开发,主要功能包括:中文分词,词性标注,命名实体识别,用户词典功能,详情见官网:http://ictclas.nlpir.org ...
- Sqlsever
Sqlsever: 获取主键当前最大值: select ident_current('tablename');