题目

已知平面内 \(n\) 个点的坐标,求欧氏距离下的第 \(k\) 远点对。


分析

先将\(k\)乘2转换为第\(k\)远有序点对。

由于\(O(n^2)\)即枚举一个点再枚举另一个点会超出时限,

一个明显的优化就是如果一堆点它们不能对点对距离产生贡献

那么就不必去枚举这些点

考虑用K-D Tree维护区间坐标最小值和坐标最大值,如果不能产生贡献直接退出,

然后在跳左区间或右区间时估价判断哪个可能产生更大贡献那么就改变访问顺序,

然后开一个全为0的小根堆判断即可


代码

#include <cstdio>
#include <cctype>
#include <algorithm>
#include <queue>
#define rr register
using namespace std;
const int N=200011;
typedef long long lll;
int ran,root,n,k;
priority_queue<lll>q;
inline signed iut(){
rr int ans=0,f=1; rr char c=getchar();
while (!isdigit(c)) f=(c=='-')?-f:f,c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans*f;
}
inline void print(int ans){
if (ans<0) putchar('-'),ans=-ans;
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
inline signed min(int a,int b){return a<b?a:b;}
inline lll max(lll a,lll b){return a>b?a:b;}
struct rec{
int p[2];
bool operator <(const rec &t)const{
return p[ran]<t.p[ran];
}
};
inline lll SQR(lll x){return x*x;}
struct KD_Tree{
int mn[N][2],mx[N][2],son[N][2]; rec p[N];
inline void pup(int now){
for (rr int i=0;i<2;++i){
mn[now][i]=mx[now][i]=p[now].p[i];
if (son[now][0]){
mn[now][i]=min(mn[now][i],mn[son[now][0]][i]);
mx[now][i]=max(mx[now][i],mx[son[now][0]][i]);
}
if (son[now][1]){
mn[now][i]=min(mn[now][i],mn[son[now][1]][i]);
mx[now][i]=max(mx[now][i],mx[son[now][1]][i]);
}
}
}
inline signed build(int l,int r,int Ran){
if (l>r) return 0;
rr int mid=(l+r)>>1;
ran=Ran,nth_element(p+l,p+mid,p+1+r);
son[mid][0]=build(l,mid-1,Ran^1);
son[mid][1]=build(mid+1,r,Ran^1);
pup(mid);
return mid;
}
inline lll calc(int t,int x){
return max(SQR(p[x].p[0]-mn[t][0]),SQR(p[x].p[0]-mx[t][0]))+max(SQR(p[x].p[1]-mn[t][1]),SQR(p[x].p[1]-mx[t][1]));
}
inline void query(int now,int x){
rr lll t=SQR(p[x].p[0]-p[now].p[0])+SQR(p[x].p[1]-p[now].p[1]);
if (t>-q.top()) q.pop(),q.push(-t);
rr lll c0=calc(son[now][0],x),c1=calc(son[now][1],x);
if (son[now][0]&&son[now][1]){
if (c0>c1&&c0>-q.top()){
query(son[now][0],x);
if (c1>-q.top()) query(son[now][1],x);
}else if (c1>-q.top()){
query(son[now][1],x);
if (c0>-q.top()) query(son[now][0],x);
}
}else if (son[now][0]){
if (c0>-q.top()) query(son[now][0],x);
}else if (son[now][1]){
if (c1>-q.top()) query(son[now][1],x);
}
}
}Tre;
signed main(){
n=iut(),k=iut()<<1;
for (rr int i=1;i<=k;++i) q.push(0);
for (rr int i=1;i<=n;++i) Tre.p[i].p[0]=iut(),Tre.p[i].p[1]=iut();
root=Tre.build(1,n,0);
for (rr int i=1;i<=n;++i) Tre.query(root,i);
return !printf("%lld",-q.top());
}

#K-D Tree#洛谷 4357 [CQOI2016]K 远点对的更多相关文章

  1. BZOJ3065 带插入区间K小值 || 洛谷P4278

    这是一道让我崩溃的题...... 然鹅洛谷上时限被改然后只有20分......好像所有人都被卡了(雾) 由于替罪羊树不是依靠旋转操作而是依靠暴力重构的方式维护树的平衡,所以我们可以考虑使用替罪羊树套区 ...

  2. 洛谷P1993 小 K 的农场(查分约束)

    /* 加深一下对查分约束的理解 建图的时候为了保证所有点联通 虚拟一个点 它与所有点相连 权值为0 然后跑SPFA判负环 这题好像要写dfs的SPFA 要不超时 比较懒 改了改重复进队的条件~ */ ...

  3. 洛谷P1066 2^k进制数(题解)(递推版)

    https://www.luogu.org/problemnew/show/P1066(题目传送) (题解)https://www.luogu.org/problemnew/solution/P106 ...

  4. 洛谷1066 2^k进制数

    原题链接 大力猜结论竟然猜对了.. 对于一对\(k,w\),我们可以把\(w\)位划分成\(k\)位一段的形式,每一段就是转换成十进制后的一位,这个从题面的解释中应该可以理解. 先不考虑可能多出(即剩 ...

  5. [洛谷P3332][ZJOI2013]K大数查询

    题目大意:有$n$个位置,$m$个操作.操作有两种: $1\;l\;r\;x:$在区间$[l,r]$每个位置加上一个数$x$ $2\;l\;r\;k:$询问$[l,r]$中第$k$大的数是多少. 题解 ...

  6. [NOIP2006] 提高组 洛谷P1066 2^k进制数

    题目描述 设r是个2^k 进制数,并满足以下条件: (1)r至少是个2位的2^k 进制数. (2)作为2^k 进制数,除最后一位外,r的每一位严格小于它右边相邻的那一位. (3)将r转换为2进制数q后 ...

  7. 洛谷P1138 第k小整数

    我偏不用sort Treap好题啊 看到只有一个人写Treap,而且写的不清楚,那我就来详细地写一下,方便新人学习 第(-1)部分:前置知识 二叉查找树:满足左子树的数据都比根节点小,右子树的数据都比 ...

  8. 洛谷P3332 [ZJOI2013]K大数查询 权值线段树套区间线段树_标记永久化

    Code: #include <cstdio> #include <algorithm> #include <string> #include <cstrin ...

  9. 洛谷P1993 小 K 的农场

    题目描述 小 K 在 Minecraft 里面建立很多很多的农场,总共 n 个,以至于他自己都忘记了每个 农场中种植作物的具体数量了,他只记得一些含糊的信息(共 m 个),以下列三种形式描 述: 农场 ...

  10. 洛谷 P1066 2^k进制数

    P1066 2^k进制数 题目描述 设r是个2^k 进制数,并满足以下条件: (1)r至少是个2位的2^k 进制数. (2)作为2^k 进制数,除最后一位外,r的每一位严格小于它右边相邻的那一位. ( ...

随机推荐

  1. Vim常用快捷键汇总

    跳到指定行 在命令行模式下输入: :n(n为指定行号)

  2. SSH 客户端

    简介 OpenSSH 的客户端是二进制程序 ssh.它在 Linux/Unix 系统的位置是/usr/local/bin/ssh. Linux 系统一般都自带 ssh,如果没有就需要安装. # Ubu ...

  3. FPGA MCS文件为什么比BIN文件烧录快

    原因 Xilinx FPGA固化FPGA程序到FLASH时,可以选择使用MCS或者BIN格式,BIN是纯二进制文件,MCS是ASCII格式的文本文件. MCS是Intel早期为MCS系列 II ISI ...

  4. spark读取和处理zip、gzip、excel、等各种文件最全的技巧总结

    一.当后缀名为zip.gzip,spark可以自动处理和读取 1.spark非常智能,如果一批压缩的zip和gzip文件,并且里面为一堆text文件时,可以用如下方式读取或者获取读取后的schema ...

  5. C++ //统计元素个数 //统计内置数据类型 //统计自定义数据类型

    1 //统计元素个数 2 3 #include<iostream> 4 #include<string> 5 #include<vector> 6 #include ...

  6. Shopee虾皮api接口 搜索商品、评价信息 python数据采集

    iDataRiver平台 https://www.idatariver.com/zh-cn/ 提供开箱即用的Shopee电商数据采集API,供用户按需调用. 接口使用详情请参考Shopee接口文档 接 ...

  7. C++ Qt开发:QNetworkAccessManager网络接口组件

    Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍如何运用QNe ...

  8. snippet n. 小片, 片断, 摘录 单词记忆

    snippet 助记:snip[剪断] + -et小词后缀. 关键是 snip 怎么记忆 snip : 拟声词,模仿剪断东西的声音. 助记单词 slip 滑 根据字母 n是done的缩写,可以 想成 ...

  9. 4时4态 加被动 例句:I will have been being done - will have be be do - 频率副词位置

    4时4态 频率副词的用法和位置:放在实义动词之前.放在be 动词之后.放在情态动词之后. 频率副词的位置一般是放在实义动词之前.放在be 动词之后.放在情态动词之后.放在be动词之后:She is s ...

  10. python文件获取并读取固定长度数据实例解析

    一 概念 1 file 操作: 文件操作一般有open,write,read,close几种,这里重点是read固定长度数据. read() 用于从文件读取指定的字节数,如果未给定或为负则读取所有. ...