4520: [Cqoi2016]K远点对

Time Limit: 30 Sec  Memory Limit: 512 MB
Submit: 490  Solved: 237
[Submit][Status][Discuss]

Description

已知平面内 N 个点的坐标,求欧氏距离下的第 K 远点对。

Input

输入文件第一行为用空格隔开的两个整数 N, K。接下来 N 行,每行两个整数 X,Y,表示一个点
的坐标。1 < =  N < =  100000, 1 < =  K < =  100, K < =  N*(N−1)/2 , 0 < =  X, Y < 2^31。

Output

输出文件第一行为一个整数,表示第 K 远点对的距离的平方(一定是个整数)。

Sample Input

10 5
0 0
0 1
1 0
1 1
2 0
2 1
1 2
0 2
3 0
3 1

Sample Output

9

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 + 堆的更多相关文章

  1. BZOJ 4520: [Cqoi2016]K远点对(k-d tree)

    Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 1162  Solved: 618[Submit][Status][Discuss] Descripti ...

  2. BZOJ4520:[CQOI2016]K远点对(K-D Tree)

    Description 已知平面内 N 个点的坐标,求欧氏距离下的第 K 远点对. Input 输入文件第一行为用空格隔开的两个整数 N, K.接下来 N 行,每行两个整数 X,Y,表示一个点 的坐标 ...

  3. BZOJ - 4520 K远点对

    题意:已知平面内 N 个点的坐标,求欧氏距离下的第 K 远点对 维护大小为2k最小堆,KD树的估值用前面提到的做法 PS.网上有人估价是使用边界四个点的最值来独立枚举,然而这样写似乎过不了 #incl ...

  4. BZOJ 3053: The Closest M Points(K-D Tree)

    Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1235  Solved: 418[Submit][Status][Discuss] Descripti ...

  5. BZOJ 1941: [Sdoi2010]Hide and Seek(k-d Tree)

    Time Limit: 16 Sec  Memory Limit: 162 MBSubmit: 1712  Solved: 932[Submit][Status][Discuss] Descripti ...

  6. BZOJ 3489: A simple rmq problem(K-D Tree)

    Time Limit: 40 Sec  Memory Limit: 512 MBSubmit: 2579  Solved: 888[Submit][Status][Discuss] Descripti ...

  7. BZOJ 2648 SJY摆棋子(KD Tree)

    http://www.lydsy.com/JudgeOnline/problem.php?id=2648 题意: 思路: KDtree模板题. 参考自http://www.cnblogs.com/ra ...

  8. BZOJ 4520 [Cqoi2016]K远点对(KD树)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4520 [题目大意] 求K远点对距离 [题解] 修改估价函数为欧式上界估价,对每个点进行 ...

  9. BZOJ 4520: [Cqoi2016]K远点对

    4520: [Cqoi2016]K远点对 Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 638  Solved: 340[Submit][Status ...

  10. BZOJ 4520: [Cqoi2016]K远点对 KDtree + 估价函数 + 堆

    Code: #include<bits/stdc++.h> #define ll long long #define maxn 200000 #define inf 10000000000 ...

随机推荐

  1. 微信v3 JSAPI最新接口错误 get_brand_wcpay_request:fail

    WxPay.JsApiPay.php文件下 原始接口代码 /** * * 获取jsapi支付的参数 * @param array $UnifiedOrderResult 统一支付接口返回的数据 * @ ...

  2. Javascript 代码格式化(JsFormat)

    JsFormat 在GitHub 上的地址: https://github.com/jdc0589/JsFormat 这是一个sublime text 2 的插件. 安装: 先安装 sublime p ...

  3. GT考试(bzoj 1009)

    Description 阿申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9),他不希望准考证号上出现不吉利的数字.他的不吉利数学A1A2...Am(0< ...

  4. ios蓝牙开发(三)ios连接外设的代码实现:手机app去读写蓝牙设备。

    手机app去读写蓝牙设备....... 代码下载: 原文博客主提供Github代码连接,地址是:https://github.com/coolnameismy/demo ios连接外设的代码实现流程: ...

  5. 在使用EF Code First开发时,遇到的“关系”问题,以及解决方法

    Entity Framework Code First 简称 EF CF也行,就是在开发的时候,以代码先行的原则,开发人员无需考虑 数据库端的一些问题(开发过程中基本不需要在数据库管理器上操作) 言归 ...

  6. Apache下开启SSI配置使html支持include包含

    写页面的同学通常会遇到这样的烦恼,就是页面上的 html 标签越来越多的时候,寻找指定的部分就会很困难,那么能不能像 javascript 一样写在不同的文件中引入呢?答案是有的,apache 能做到 ...

  7. JAVA GC 简单总结

    GC分代 GC的英文全拼是Garbage Collection,意思是垃圾收集. Java 将堆内存分为三代来管理: - 年轻代 (Young Generation) - 年老代 (Old Gener ...

  8. Linux运维教程

    最近看马哥Linux运维,收益颇多.愿马哥,身体健康! 2013马哥全套 http://pan.baidu.com/s/1c0JQu9i 运维技术文档 http://pan.baidu.com/s/1 ...

  9. 1017关于EXPLAIN的语法

    转自博客 http://blog.csdn.net/zhuxineli/article/details/14455029 explain显示了MySQL如何使用索引来处理select语句以及连接表.可 ...

  10. canvas模拟重力效果

    总结 速度和加速度是动画的基础元素,其中两者都是向量,包括了一个重要因素:方向. 要学会应用 分解 和 合成 ,将速度或加速度分解到x.y轴上,然后将每条轴上的加速度或速度相加,然后再分别与物体的位置 ...