Time Limit: 30 Sec  Memory Limit: 512 MB
Submit: 588  Solved: 309
[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

【题解】

第K远点对。是说C(N,2)个点对里面。点对之间的距离是第K远的。求这个距离。

我们枚举每个点。然后查看它与其他点的距离。

维护一个1..2*K远的队列。然后不断更新这个队列

(为什么是2*k,想想我们在枚举第一个点的时候,假如和第3个点配对,距离为第2远那么下次再枚举第3个点的时候还会遇到第一个点。又出现了一个第2远的数要加入到队列中。而这两个距离其实是同一个点对的。即排列。考虑其他第1,3,4,..k远的点对也会出现这种情况。我们就把K变成2*K。);

【代码】

#include <cstdio>
#include <algorithm>using namespace std;const int MAX_N = 109000;int n, k,root,now;
long long duilie[300];struct point
{long long d[2], mi_n[2], ma_x[2] ;int l,r;
};point t[MAX_N],op;void input_data()
{scanf("%d%d", &n, &k);for (int i = 1; i <= n; i++)scanf("%lld%lld", &t[i].d[0], &t[i].d[1]);
}bool cmp(point a, point b)
{return a.d[now] < b.d[now];
}void up_data(int rt)
{int l = t[rt].l, r = t[rt].r;for (int i = 0; i <= 1; i++){if (l){t[rt].ma_x[i] = max(t[rt].ma_x[i], t[l].ma_x[i]);t[rt].mi_n[i] = min(t[rt].mi_n[i], t[l].mi_n[i]);}if (r){t[rt].ma_x[i] = max(t[rt].ma_x[i], t[r].ma_x[i]);t[rt].mi_n[i] = min(t[rt].mi_n[i], t[r].mi_n[i]);}}
}int build(int begin, int end, int fx)
{int m = (begin + end) >> 1;now = fx;nth_element(t + begin, t + m, t + end + 1, cmp);for (int i = 0; i <= 1; i++)t[m].ma_x[i] = t[m].mi_n[i] = t[m].d[i];if (begin < m)t[m].l = build(begin, m - 1, 1 - fx);if (m < end)t[m].r = build(m + 1, end, 1 - fx);up_data(m);return m;
}long long sqr(long long x)
{return x*x;
}long long get_dis(int rt)
{return sqr(t[rt].d[0] - op.d[0]) + sqr(t[rt].d[1] - op.d[1]);
}long long gujia(int rt)//估价函数
{long long temp = 0;for (int i = 0; i <= 1; i++)temp += max(sqr(t[rt].mi_n[i] - op.d[i]), sqr(t[rt].ma_x[i] - op.d[i]));return temp;
}void query(int rt)
{long long dis = get_dis(rt);int k_th = k;while (duilie[k_th] <= dis)//找到这个距离在队列中的合适位置。{k_th--;if (!k_th)break;}if (k_th != k){for (int i = k; i >= k_th + 2; i--)duilie[i] = duilie[i - 1];//这个位置后面的数字往后挪。duilie[k_th + 1] = dis;}int l = t[rt].l, r = t[rt].r;long long gl = -1,gr = -1;if (l)gl = gujia(l);if (r)gr = gujia(r);if (gl < gr){if (gr >= duilie[k])query(r);if (gl >= duilie[k])query(l);}else{if (gl >= duilie[k])query(l);if (gr >= duilie[k])query(r);}
}void get_ans()
{root = build(1, n, 0);k = k * 2;//直接求2*k远for (int i = 1; i <= k; i++)//duilie[1..k]分别表示第1,2,3..远。因此它是递减队列。duilie[i] = 0;for (int i = 1; i <= n; i++){op.d[0] = t[i].d[0], op.d[1] = t[i].d[1];query(root);}
}void output_ans()
{printf("%lld\n", duilie[k]);
}int main()
{//freopen("F:\\rush.txt", "r", stdin);input_data();get_ans();output_ans();return 0;
}

转载于:https://www.cnblogs.com/AWCXV/p/7632234.html

【52.55%】【BZOJ 4520】K远点对相关推荐

  1. BZOJ - 4520 K远点对

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

  2. 4520: [Cqoi2016]K远点对

    4520: [Cqoi2016]K远点对 Time Limit: 30 Sec   Memory Limit: 512 MB Submit: 594   Solved: 314 [ Submit][ ...

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

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

  4. 编写高质量代码:改善Java程序的151个建议(第4章:字符串___建议52~55)

    建议52:推荐使用String直接量赋值 一般对象都是通过new关键字生成的,但是String还有第二种生成方式,也就是我们经常使用的直接声明方式,这种方式是极力推荐的,但不建议使用new Strin ...

  5. 转载--编写高质量代码:改善Java程序的151个建议(第4章:字符串___建议52~55)

    阅读目录 建议52:推荐使用String直接量赋值 建议53:注意方法中传递的参数要求 建议54:正确使用String.StringBuffer.StringBuilder 建议55:注意字符串的位置 ...

  6. P4357-[CQOI2016]K远点对【K-Dtree】

    正题 题目链接:https://www.luogu.com.cn/problem/P4357 题目大意 平面上给出nnn个点,求第kkk远的点对距离. 解题思路 K-Dtree\text{K-Dtre ...

  7. Chapter 8(查找)

    1.二分查找和插值查找 //************************Search.h*********************************** #ifndef SEARCH_H # ...

  8. 家族关系查询系统程序设计算法思路_七大查找算法(附C语言代码实现)

    来自:Poll的笔记 - 博客园 链接:http://www.cnblogs.com/maybe2030/p/4715035.html 阅读目录 1.顺序查找 2.二分查找 3.插值查找 4.斐波那契 ...

  9. 华为交换机系统版本升级(S7706)

    本案例为S7706 r012升级到R019,内含X系列单板作为无线AC控制器,slot7\8分别为主备双控制器 [10:28:19]<GZLZ-4F-4F01-S7706-CORE-1>d ...

最新文章

  1. OKR落地的四个基本因素是什么?
  2. 【风之语】至贱城市之苏州
  3. C++五子棋(一)——开发环境
  4. swift编写命令行工具
  5. 图文讲解5G调制,特别通俗易懂!
  6. Java程序员该如何学习才能成长为一名优秀的架构师
  7. 如何打开屏幕坏的手机_手机屏幕碎了怎么开usb?不通过屏幕打开usb调试方法
  8. 论文润色软件Stylewriter,whitesmoke,1check使用亲测
  9. CDA 数据分析师 Level1 基本知识(4)--统计学原理
  10. BZOJ4134: ljw和lzr的hack比赛
  11. ad电阻原理图_arduino传感器专辑之光敏电阻模块
  12. 微信公众号里放XLS链接教程
  13. Google BERT 中文应用之《红楼梦》中对话人物提取
  14. 简单的计算机程序图,技巧:只需几个简单的步骤,即可使用Office工具离线识别图片文字...
  15. NVIDIA显卡的的CUDA核心是什么?
  16. 网站服务器宕机怎么办,服务器宕机了该怎么办?
  17. 基于Hyper-V、centos、搭建宝塔Linux结合gitLab实现前端自动化部署
  18. piaget读法_罗读音【罗读音英语头条】- 罗读音知识点 - 中企动力
  19. 房友系统连接不上服务器,房友系统服务器地址
  20. Ubuntu 20.04 安装Metasploit msfconsole

热门文章

  1. 回溯法 —— 求解0/1背包问题(剪枝)
  2. 数据库、数据库系统、数据库管理系统
  3. Wannafly模拟赛2: A. Contest(Cdq分治)
  4. bzoj 1654: [Usaco2006 Jan]The Cow Prom 奶牛舞会(Trajan)
  5. sort函数的使用(c++) bool函数使用
  6. hadoop、hbase、hive、spark分布式系统架构原理
  7. 安卓接收耳机按键控制音频播放
  8. matlab2c使用c++实现matlab函数系列教程-raylpdf函数
  9. 均匀带电的无限大平面划成无限长直线积分计算场强
  10. mysql 单向复制_Mysql 复制(Replication)实现