KD-tree+堆

多年大坑

KD-tree已经是半年前学的了,忘记了。这道题当时一直T,今天重新抄了一遍,A了

KD-tree过程:1.建树:每次依次按x,y划分平面,像二叉搜索树一样建树,每个点维护一些东西;

2.查询:直接查太暴力了,我们用估价函数减值,每个点维护最小最大的x和y,每次计算能够造成的最大距离,如果有价值就递归。注意关于dl,dr的大小判断,这里query顺序不一样,因为先query大的会使大的先进堆,这样更快一些,相当于一个剪枝。其实KD-tree就是一个暴力剪枝的过程。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll inf = 1e18;
const int N = 1e5 + ;
int n, k, root, d;
struct data {
ll mx_x, mn_x, mx_y, mn_y, x, y, lc, rc;
bool friend operator < (const data &a, const data &b) {
if(d == ) return a.x == b.x ? a.y < b.y : a.x < b.x;
if(d == ) return a.y == b.y ? a.x < b.x : a.y < b.y;
}
} a[N];
priority_queue<ll, vector<ll>, greater<ll> > q;
ll sqr(ll x)
{
return x * x;
}
ll dis(int k, ll x, ll y)
{
return max(sqr(a[k].mn_x - x), sqr(a[k].mx_x - x)) + max(sqr(a[k].mn_y - y), sqr(a[k].mx_y - y));
}
void update(int x)
{
a[x].mn_x = min(a[x].x, min(a[a[x].lc].mn_x, a[a[x].rc].mn_x));
a[x].mx_x = max(a[x].x, max(a[a[x].lc].mx_x, a[a[x].rc].mx_x));
a[x].mn_y = min(a[x].y, min(a[a[x].lc].mn_y, a[a[x].rc].mn_y));
a[x].mx_y = max(a[x].y, max(a[a[x].lc].mx_y, a[a[x].rc].mx_y));
}
int build(int l, int r, int now)
{
if(l > r) return ;
int mid = (l + r) >> ;
d = now;
nth_element(a + l, a + mid, a + r + );
a[mid].mx_x = a[mid].mn_x = a[mid].x;
a[mid].mx_y = a[mid].mn_y = a[mid].y;
a[mid].lc = build(l, mid - , now ^ );
a[mid].rc = build(mid + , r, now ^ );
update(mid);
return mid;
}
void query(int k, ll x, ll y)
{
ll tmp = sqr(x - a[k].x) + sqr(y - a[k].y), dl = a[k].lc ? dis(a[k].lc, x, y) : -inf, dr = a[k].rc ? dis(a[k].rc, x, y) : -inf;
if(tmp > q.top()) q.pop(), q.push(tmp);
if(dl < dr)
{
if(dr > q.top()) query(a[k].rc, x, y);
if(dl > q.top()) query(a[k].lc, x, y);
}
else
{
if(dl > q.top()) query(a[k].lc, x, y);
if(dr > q.top()) query(a[k].rc, x, y);
}
}
int main()
{
scanf("%d%d", &n, &k);
a[].mn_x = inf;
a[].mx_x = -inf;
a[].mn_y = inf;
a[].mx_y = -inf;
for(int i = ; i <= n; ++i) scanf("%d%d", &a[i].x, &a[i].y);
root = build(, n, );
for(int i = ; i <= * k; ++i) q.push();
for(int i = ; i <= n; ++i) query(root, a[i].x, a[i].y);
printf("%lld\n", q.top());
return ;
}

bzoj4520的更多相关文章

  1. BZOJ4520 CQOI2016K远点对(KD-Tree+堆)

    堆维护第k大,每个点KD-Tree上A*式查询较远点,跑得飞快,复杂度玄学. #include<iostream> #include<cstdio> #include<c ...

  2. 【bzoj4520】 Cqoi2016—K远点对

    http://www.lydsy.com/JudgeOnline/problem.php?id=4520 (题目链接) 题意 求平面内第K远点对的距离. Solution 左转题解:jump 细节 刚 ...

  3. 【bzoj4520】K远点对

    Portal --> bzoj4520 Description 给你平面内\(n\)个点的坐标,求欧氏距离下第\(k\)远的点对 Solution 因为kd其实..严格来说挺不熟的用的太少了qw ...

  4. 【BZOJ4520】K远点对(KD-Tree)

    [BZOJ4520]K远点对(KD-Tree) 题面 BZOJ 洛谷 题解 考虑暴力. 维护一个大小为\(K\)的小根堆,然后每次把两个点之间的距离插进去,然后弹出堆顶 这样子可以用\(KD-Tree ...

  5. 【BZOJ4520】[Cqoi2016]K远点对 kd-tree+堆

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

  6. [bzoj4520][Cqoi2016]K远点对_KD-Tree_堆

    K远点对 bzoj-4520 Cqoi-2016 题目大意:已知平面内 N 个点的坐标,求欧氏距离下的第 K 远点对. 注释:$1\le n\le 10^5$,$1\le k\le 100$,$k\l ...

  7. BZOJ4520 [Cqoi2016]K远点对

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000作者博客:http://www.cnblogs.com/ljh2000-jump/转 ...

  8. 【BZOJ-4520】K远点对 KD-Tree + 堆

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

  9. bzoj4520【CQOI2016】K远点对

    题解: kd-tree裸题 对每个点维护最近的k个开个堆维护一下

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

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

随机推荐

  1. 判断是否是iso8859-1编码

    if (null == keyword || keyword.equals("关键字")) keyword = "";            if(keywor ...

  2. 小胖说事20--------GCD笔记

    1.系统提供的dispatch方法 为了方便的使用GCD.苹果提供了一些方法方便我们将BLOCK放在主线程或者后台程序运行.或者延后运行. //后台运行: dispatch_async(dispatc ...

  3. C和C++代码精粹笔记1

    CH1 更好的C 运算符重载规定,必须有一个为用户自定义类型 一些输出没注意到的函数: float x = 123.456, y = 12345; //cout.precision(2); //显示两 ...

  4. WinDbg抓取dmp文件

    应用程序发生异常时抓取dmp: adplus.vbs -crash -pn w3wp.exe -y srv*c:\symbols*http://msdl.microsoft.com/download/ ...

  5. sonar+Jenkins代码覆盖率检测

    最近公司在搞代码覆盖率检查,简单看了一下结合Jenkins +jacoco + sonar做了一下主要涉及到项目层面和Jenkins层面的东西: 这里只讲一下集成,不讲解sonar的安装Jenkins ...

  6. Ffmpeg 实现文件切割

    文件切割是一项很常见的基本功能,通过Ffmpeg可以很容易实现这项功能. 首先介绍下基本原理,文件切割说白了就过滤掉文件的部分音视频包,按照什么规则过滤呢? 答案是时间戳.文件中每个视频及音频包都有时 ...

  7. start-dfs.sh 和 start-all.sh的区别

    start-dfs.sh 只启动namenode 和datanode, start-all.sh还包括yarn的resourcemanager 和nodemanager 之前就所以因为只启动了star ...

  8. 韦东山 第9课第1节.u-boot分析之编译体验 http://www.100ask.net/index.html

    http://www.100ask.net/index.html 韦东山官网网址 http://wenku.baidu.com/view/ae78a00390c69ec3d5bb75ce.html h ...

  9. Django框架学习——python模拟Django框架(转载)

    原贴来源 http://wiki.woodpecker.org.cn/moin/ObpLovelyPython/AbtWebModules python实现web服务器 web开发首先要有web服务器 ...

  10. 《AndroidStudio有用指南》反馈问题和建议

    <AndroidStudio有用指南>反馈问题和建议 IntelliJ IDEA在持续更新, Android Studio也在持续更新, 本书也将会持续更新. Android Studio ...