BZOJ 4520: [Cqoi2016]K远点对(k-d tree)
Time Limit: 30 Sec Memory Limit: 512 MB
Submit: 1162 Solved: 618
[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
自己yy了一波,过了样例就A了hhh
考虑到$k$很小,因此我们可以维护一个$2*k$个点的小根堆去维护每个点对(每个点对会被统计两次)
然后在K-D tree上暴力,如果当前点对的距离比堆顶的距离大,就把堆顶删除,然后把当前点加入
时间复杂度$O(n \sqrt(n))?$
// luogu-judger-enable-o2
// luogu-judger-enable-o2
#include<cstdio>
#include<algorithm>
#include<queue>
#define int long long
#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
using namespace std;
const int MAXN = , INF = 1e9 + ;
char buf[ << ], *p1 = buf, *p2 = buf;
inline int read() {
char c = getchar(); int x = , f = ;
while(c < '' || c > '') {if(c == '-') f = -; c = getchar();}
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x * f;
}
int N, K;
priority_queue<int, vector<int>, greater<int> > q;
int root, WD, cur = ;
#define ls(k) T[k].ls
#define rs(l) T[k].rs
struct Point {
int x[];
bool operator < (const Point &rhs) const {
return x[WD] < rhs.x[WD];
}
}p[MAXN];
struct KDtree {
int ls, rs, mi[], mx[];
Point tp;
}T[MAXN];
inline int sqr(int x) {
return x * x;
}
void update(int k) {
for(int i = ; i <= ; i++) {
T[k].mi[i] = T[k].mx[i] = T[k].tp.x[i];
if(ls(k)) T[k].mi[i] = min(T[k].mi[i], T[ls(k)].mi[i]), T[k].mx[i] = max(T[k].mx[i], T[ls(k)].mx[i]);
if(rs(k)) T[k].mi[i] = min(T[k].mi[i], T[rs(k)].mi[i]), T[k].mx[i] = max(T[k].mx[i], T[rs(k)].mx[i]);
}
}
int Build(int l, int r, int wd) {
if(l > r) return ;
WD = wd;
int k = ++cur, mid = l + r >> ;
nth_element(p + l, p + mid, p + r + );
T[k].tp = p[mid];
T[k].ls = Build(l, mid - , wd ^ );
T[k].rs = Build(mid + , r, wd ^ );
update(k);
return k;
}
int dis(Point a, Point b) {
return sqr(a.x[] - b.x[]) + sqr(a.x[] - b.x[]);
}
int GetMaxDis(KDtree a, Point b) {
int rt = ;
for(int i = ; i <= ; i++)
rt += sqr(max(abs(b.x[i] - a.mi[i]), abs(b.x[i] - a.mx[i])));
return rt;
}
void Query(int k, Point a) {
int tmp = q.top(), tmpdis = dis(T[k].tp, a);
if(tmpdis > tmp) q.pop(), q.push(tmpdis);
int disl = -INF, disr = -INF;
if(ls(k)) disl = GetMaxDis(T[ls(k)], a);
if(rs(k)) disr = GetMaxDis(T[rs(k)], a);
if(disl > disr) {
if(disl > q.top()) Query(ls(k), a);
if(disr > q.top()) Query(rs(k), a);
}
else {
if(disr > q.top()) Query(rs(k), a);
if(disl > q.top()) Query(ls(k), a);
}
}
main() {
#ifdef WIN32
freopen("a.in", "r", stdin);
#endif
N =read(); K = read();
for(int i = ; i <= N; i++)
p[i].x[] = read(), p[i].x[] = read();
root = Build(, N, );
for(int i = ; i <= * K; i++)
q.push();
for(int i = ; i <= N; i++)
Query(root, p[i]);
printf("%lld", q.top());
}
BZOJ 4520: [Cqoi2016]K远点对(k-d tree)的更多相关文章
- BZOJ 4520: [Cqoi2016]K远点对
4520: [Cqoi2016]K远点对 Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 638 Solved: 340[Submit][Status ...
- BZOJ 4520 [Cqoi2016]K远点对(KD树)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4520 [题目大意] 求K远点对距离 [题解] 修改估价函数为欧式上界估价,对每个点进行 ...
- BZOJ 4520: [Cqoi2016]K远点对 KDtree + 估价函数 + 堆
Code: #include<bits/stdc++.h> #define ll long long #define maxn 200000 #define inf 10000000000 ...
- BZOJ - 4520 K远点对
题意:已知平面内 N 个点的坐标,求欧氏距离下的第 K 远点对 维护大小为2k最小堆,KD树的估值用前面提到的做法 PS.网上有人估价是使用边界四个点的最值来独立枚举,然而这样写似乎过不了 #incl ...
- 【52.55%】【BZOJ 4520】K远点对
Time Limit: 30 Sec Memory Limit: 512 MB Submit: 588 Solved: 309 [Submit][Status][Discuss] Descript ...
- [Cqoi2016]K远点对 K-Dtree
4520: [Cqoi2016]K远点对 链接 bzoj 思路 用K-Dtree求点的最远距离. 求的时候顺便维护一个大小为2k的小根堆. 不知道为啥一定会对. 代码 #include <bit ...
- [BZOJ4520][Cqoi2016]K远点对 kd-tree 优先队列
4520: [Cqoi2016]K远点对 Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 1285 Solved: 708[Submit][Statu ...
- 【bzoj4520】 Cqoi2016—K远点对
http://www.lydsy.com/JudgeOnline/problem.php?id=4520 (题目链接) 题意 求平面内第K远点对的距离. Solution 左转题解:jump 细节 刚 ...
- 【BZOJ4520】[Cqoi2016]K远点对 kd-tree+堆
[BZOJ4520][Cqoi2016]K远点对 Description 已知平面内 N 个点的坐标,求欧氏距离下的第 K 远点对. Input 输入文件第一行为用空格隔开的两个整数 N, K.接下来 ...
随机推荐
- Grunt入门学习之(2) -- Gruntfile的编写
Gruntfile由以下几部分构成: "wrapper" 函数 项目与任务,目标配置 加载grunt插件和任务 自定义任务 1.wrapper函数(包装函数) 每一个 Gruntf ...
- flask多线程多协程操作
local的作用:各个线程各开辟一块空间互不影响 基于local""" import threading from threading import local impo ...
- androidcookie存储sqllite
/**声明一些数据库操作的常量*/ private static SQLiteDatabase mDatabase = null; private static final String DATA ...
- Redis(一):centos下安装。
yum install gcc-cc++ wget http://download.redis.io/releases/redis-4.0.2.tar.gz .tar.gz /usr/local cd ...
- Java Spring中@Query中使用JPQL LIKE 写法
两种方式 // 一 public List<TestEntity> searchByJpql(){ String jpql = "select k from TestEntity ...
- Linux入门-4 Linux下获取帮助
help MAN INFO doc help <command> -h或<command> --help whatis <cmd> MAN man <comm ...
- Effective C++(5) 了解C++默默地编写并调用哪些函数
预热: 一个空的类,当编译器处理过之后,就包含: 一个copy构造函数 一个重载赋值操作符 一个析构函数 一个默认构造函数 Demo: class Empty() { }; // 声明一个空的类 cl ...
- 计算机用CMD命令关机建立文件夹 梁华杰
1:进入CMD BJ 2:关机并取消 3:进入D盘 文件管理 创件文件并删除
- C/S架构的性能测试
很多人关心LR在C/S架构上如何实施性能测试,我想根本原因在于两个方面,一是很多时候脚本无法录制,即LR无法成功调用被测的应用程序,二是测试脚本即使录制下来,可读性不强,往往不能运行通过,调试时无从下 ...
- MTK 官方 openwrt SDK 使用
来源 1.https://github.com/unigent/openwrt-3.10.14 上面有个 问题:SDK 缺少 linux-3.10.14-p112871.tar.xz 在 http ...