浅谈\(K-D\) \(Tree\):https://www.cnblogs.com/AKMer/p/10387266.html

题目传送门:https://lydsy.com/JudgeOnline/problem.php?id=4520

说实话,写了这个题之后我才明白\(K-D\) \(Tree\)最优美的地方。

那就是剪枝。

用堆维护前\(2k\)远的点对,如果当前子树内里询问点最远的距离都比堆顶小那么就直接退出。

时间复杂度:\(O(nlogn)\)

空间复杂度:\(O(n)\)

代码如下:

#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
#define sqr(x) (1ll*(x)*(x)) const int maxn=1e5+5,inf=2147483647; int n,k,pps,X,Y; int read() {
int x=0,f=1;char ch=getchar();
for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
return x*f;
} struct heap {
int tot;
ll tree[maxn]; void ins(ll v) {
tree[++tot]=v;int pos=tot;
while(pos>1) {
if(tree[pos]<tree[pos>>1])
swap(tree[pos],tree[pos>>1]),pos>>=1;
else break;
}
} void pop() {
tree[1]=tree[tot--];
int pos=1,son=2;
while(son<=tot) {
if(son<tot&&tree[son|1]<tree[son])son|=1;
if(tree[son]<tree[pos])
swap(tree[pos],tree[son]),pos=son,son=pos<<1;
else break;
}
}
}H; struct kd_tree {
int root; struct point {
int ls,rs;
int c[2],mn[2],mx[2]; bool operator<(const point &a)const {
return c[pps]<a.c[pps];
}
}p[maxn]; int build(int l,int r,int d) {
int mid=(l+r)>>1,u=mid;pps=d;
nth_element(p+l,p+mid,p+r+1);
if(l<mid)p[u].ls=build(l,mid-1,d^1);
if(r>mid)p[u].rs=build(mid+1,r,d^1);
int ls=p[u].ls,rs=p[u].rs;
for(int i=0;i<2;i++) {
int mn=min(p[ls].mn[i],p[rs].mn[i]);
p[u].mn[i]=min(p[u].c[i],mn);
int mx=max(p[ls].mx[i],p[rs].mx[i]);
p[u].mx[i]=max(p[u].c[i],mx);
}
return u;
} void prepare() {
p[0].mn[0]=p[0].mn[1]=inf;
p[0].mx[0]=p[0].mx[1]=-inf;
for(int i=1;i<=n;i++)
p[i].c[0]=read(),p[i].c[1]=read();
root=build(1,n,0);
} ll dis(int u) {
ll a=max(abs((ll)p[u].mn[0]-X),abs((ll)p[u].mx[0]-X));
ll b=max(abs((ll)p[u].mn[1]-Y),abs((ll)p[u].mx[1]-Y));
return sqr(a)+sqr(b);
} void query(int u) {
if(!u)return;
if(H.tot==k&&dis(u)<H.tree[1])return;
ll dist=sqr(abs((ll)X-p[u].c[0]))+sqr(abs((ll)Y-p[u].c[1]));
if(H.tot!=k||dist>H.tree[1]) {
H.ins(dist);if(H.tot>k)H.pop();
}
ll dl=p[u].ls?dis(p[u].ls):-sqr(inf);
ll dr=p[u].rs?dis(p[u].rs):-sqr(inf);
if(dl>dr)query(p[u].ls),query(p[u].rs);
else query(p[u].rs),query(p[u].ls);
}
}T; int main() {
n=read(),k=read()<<1;
T.prepare();
for(int i=1;i<=n;i++)
X=T.p[i].c[0],Y=T.p[i].c[1],T.query(T.root);
printf("%lld\n",H.tree[1]);
return 0;
}

BZOJ4520:[CQOI2016]K远点对的更多相关文章

  1. [BZOJ4520][Cqoi2016]K远点对 kd-tree 优先队列

    4520: [Cqoi2016]K远点对 Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 1285  Solved: 708[Submit][Statu ...

  2. [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 ...

  3. BZOJ4520 [Cqoi2016]K远点对

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

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

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

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

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

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

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

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

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

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

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

  9. [Cqoi2016]K远点对 K-Dtree

    4520: [Cqoi2016]K远点对 链接 bzoj 思路 用K-Dtree求点的最远距离. 求的时候顺便维护一个大小为2k的小根堆. 不知道为啥一定会对. 代码 #include <bit ...

  10. 【bzoj4520】 Cqoi2016—K远点对

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

随机推荐

  1. 20145240《Java程序设计》第一周学习总结

    20145240 <Java程序设计>第一周学习总结 教材学习内容总结 第一周学习Java首先从最基本的下载.配置环境.了解基本人机命令行方式等基础知识,以及编写简单的"Hell ...

  2. centos7下安装jdk7

     CentOS7.1 JDK安装 1.卸载自带OPENJDK    用 java -version 命令查看当前jdk版本信息   #java -version    用rpm -qa | grep ...

  3. Git使用http clone客户端保存用户名密码

    使用Git Bash时,用命令git pull或git push时总是要输入密码,很烦躁 解决办法 需要注意的是,这个方法是在Windows下使用 1. 新建环境变量   HOME 值为 %USERP ...

  4. 常见Web安全漏洞

    1.web安全常见攻击手段     xss  sql注入  防盗链  csrf  上传漏洞 2. 信息加密与漏洞扫描   对称加密 非对称加密 3. 互联网API接口安全设计 4. 网站安全漏洞扫描与 ...

  5. vc 自删除

    // delself.cpp : 定义控制台应用程序的入口点.// #include "stdafx.h"#include <windows.h>#include &l ...

  6. 转:Android命令Monkey压力测试,详解

    停止Monkey命令: 1. ps命令  查找uiautomator的进程 打开cmd命令行窗口 输入: adb shell ps | grep monkey 返回来的第一个数字,即是monkey的进 ...

  7. 在openrc中从keystone V2 到 V3

    #!/bin/bash ] then echo "Usage $0 <keystone.rc>" exit fi . $ NEW_OS_AUTH_URL=`echo $ ...

  8. SQL 存在一个表而不在另一个表中的数据

    原文链接:http://blog.csdn.net/windren06/article/details/8188136 (转)A.B两表,找出ID字段中,存在A表,但是不存在B表的数据.A表总共13w ...

  9. Codeforces Round #435 (Div. 2) c+d

    C:给n和k要求,找出n个不同的数,使得亦或起来等于k 可以先预处理从1到1e5,找亦或起来等于(11111111111111111)(二进制)的所有对数,然后四个一起亦或就是0了,再和k亦或 可以看 ...

  10. Swift 3.0 on Ubuntu 15.10

    一.安装swift 3.0 1. 下载 https://swift.org/download/ 找到swift-3.0 ubuntu 15.10版本下载: https://swift.org/buil ...