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. 伯克利AI研究院解析「反向课程学习」,改善「强化学习智能体」并应用于机器人技术
  2. 【转】Odoo装饰器: one装饰
  3. 你以为A10 Networks只做应用交付?
  4. 并发工具类(一)等待多线程完成的CountDownLatch
  5. 利用dft的定义计算dft的matlab程序_CP2K教程系列之静态计算(Pymatflow篇)
  6. 竞赛数据清洗缺失值_Kaggle 数据清洗挑战 Day 1 - 手把手教你五步处理缺失值
  7. HTTP1.0 HTTP1.1 HTTP2.0 主要特性对比
  8. LEFT OUTER JOIN
  9. 使用Sharepoint Services 3.0构建基本网站
  10. 2022阿里笔试分享(2022.3.25)
  11. WPF基本控件的简介(二)
  12. 使用CollectionView简单实现轮播广告栏效果
  13. excel查询oracle数据库,用Excel直接查询Oracle中的数据
  14. SpringBoot整合GraphQL第(一)章节
  15. SAP系统接口对接历险记
  16. 修改MYSQL 表中的字段属性
  17. php抽奖的数字滚动器,jQuery数字滚动插件
  18. Qt在linux和widows下获取IP列表,网关,子网掩码,广播地址
  19. SaaSpace:2022年十大最好的免费动画软件
  20. 【无私分享】修订版干货!!!一个炫酷的自定义日历控件,摆脱日历时间选择烦恼,纯福利~...

热门文章

  1. python条件语句代码例子_Python 炫技操作:条件语句的七种写法
  2. 经典问题莫比乌斯反演gcd(a,b)==kGuGuFishtion好题
  3. ubuntu装python3_ubuntu16.04安装python3的包报错
  4. 下载并搭建VauditDemo
  5. bzoj 4950: [Wf2017]Mission Improbable(二分匹配)
  6. bzoj 1034: [ZJOI2008]泡泡堂BNB(贪心)
  7. bzoj 1658: [Usaco2006 Mar]Water Slides 滑水(贪心)
  8. NYOJ 82:迷宫寻宝(一)(BFS)
  9. python3 round函数
  10. rancher 使用部分运维操作