BZOJ4520:[CQOI2016]K远点对
浅谈\(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远点对的更多相关文章
- [BZOJ4520][Cqoi2016]K远点对 kd-tree 优先队列
4520: [Cqoi2016]K远点对 Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 1285 Solved: 708[Submit][Statu ...
- [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 ...
- BZOJ4520 [Cqoi2016]K远点对
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000作者博客:http://www.cnblogs.com/ljh2000-jump/转 ...
- BZOJ4520:[CQOI2016]K远点对(K-D Tree)
Description 已知平面内 N 个点的坐标,求欧氏距离下的第 K 远点对. Input 输入文件第一行为用空格隔开的两个整数 N, K.接下来 N 行,每行两个整数 X,Y,表示一个点 的坐标 ...
- 【BZOJ4520】[Cqoi2016]K远点对 kd-tree+堆
[BZOJ4520][Cqoi2016]K远点对 Description 已知平面内 N 个点的坐标,求欧氏距离下的第 K 远点对. Input 输入文件第一行为用空格隔开的两个整数 N, K.接下来 ...
- 【BZOJ-4520】K远点对 KD-Tree + 堆
4520: [Cqoi2016]K远点对 Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 490 Solved: 237[Submit][Status ...
- BZOJ 4520: [Cqoi2016]K远点对
4520: [Cqoi2016]K远点对 Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 638 Solved: 340[Submit][Status ...
- 【BZOJ4520】K远点对(KD-Tree)
[BZOJ4520]K远点对(KD-Tree) 题面 BZOJ 洛谷 题解 考虑暴力. 维护一个大小为\(K\)的小根堆,然后每次把两个点之间的距离插进去,然后弹出堆顶 这样子可以用\(KD-Tree ...
- [Cqoi2016]K远点对 K-Dtree
4520: [Cqoi2016]K远点对 链接 bzoj 思路 用K-Dtree求点的最远距离. 求的时候顺便维护一个大小为2k的小根堆. 不知道为啥一定会对. 代码 #include <bit ...
- 【bzoj4520】 Cqoi2016—K远点对
http://www.lydsy.com/JudgeOnline/problem.php?id=4520 (题目链接) 题意 求平面内第K远点对的距离. Solution 左转题解:jump 细节 刚 ...
随机推荐
- WebSocket 的后记
一个美好的概念可以让策划无比幼稚和疯狂, 比如 H5 改变世界呀,小程序替代 APP 呀,现在即时通信也被公司里的他们认为 so easy 了. 这很尴尬好吧,WebSocket(以下简称 ws) 的 ...
- Qt事件机制---信号通过事件实现,事件可以过滤,事件更底层,事件是基础,信号是扩展。
转:http://www.cnblogs.com/findumars/p/8001484.html Qt事件机制(是动作发生后,一种通知对象的消息,是被动与主动的总和.先处理自己队列中的消息,然后再处 ...
- DNS 递归/迭代 原理
递归查询 递归:客户端只发一次请求,要求对方给出最终结果.一般客户机和服务器之间属递归查询,即当客户机向DNS服务器发出请求后,若DNS服务器本身不能解析,则会向另外的DNS服务器发出查询请求,得到结 ...
- Python绿色版
Python 安装的时候,有个选项,是问你要安装给所有用户还是只安装给当前用户,你只要选择当前用户,就会把那些需要的 dll ,包括 msvcr90.dll 都给装到 Python 目录下,你只要把 ...
- linux 无密码登录
环境:Linux 脚本:Python 功能:批量IP,远程执行命令.拷贝文件 运行:./ssh_scp.py iplist.txt 脚本内容: #!/usr/bin/env python# -*- c ...
- ibecon后台运行
程序被硬关闭后,只能执行这三个回调,而且必须写在appdelegate中,退出ibeacons信息区域时会有延时10秒左右,进入时无延时 - (void)locationManager:(CLLoca ...
- C++中substr的用法
C++中substr函数的用法 #include<string> #include<iostream> using namespace std; void main() { s ...
- QT 使用QPainter 绘制图形 和 世界变换 world transform
1. 绘制椭圆 饼状型 贝塞尔曲线 绘制图像重写方法 void paintEvent(QPaintEvent *event)即可. void Widget::paintEvent(QPaintEve ...
- JAVA8新特性——方法引用
JAVA9都要出来了,JAVA8新特性都没搞清楚,是不是有点掉队哦~ 在Lamda新特性的支持下,JAVA8中可以使用lamda表达式来创建匿名方法.然而,有时候我们仅仅是需要调用一个已存在的方法(如 ...
- js添加后缀防止缓存
jsp页面: 时间戳的话需要引入: <%@ page import="java.util.Date"%> <script type="text/java ...