#K-D Tree#洛谷 4357 [CQOI2016]K 远点对
题目
已知平面内 \(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 远点对的更多相关文章
- BZOJ3065 带插入区间K小值 || 洛谷P4278
这是一道让我崩溃的题...... 然鹅洛谷上时限被改然后只有20分......好像所有人都被卡了(雾) 由于替罪羊树不是依靠旋转操作而是依靠暴力重构的方式维护树的平衡,所以我们可以考虑使用替罪羊树套区 ...
- 洛谷P1993 小 K 的农场(查分约束)
/* 加深一下对查分约束的理解 建图的时候为了保证所有点联通 虚拟一个点 它与所有点相连 权值为0 然后跑SPFA判负环 这题好像要写dfs的SPFA 要不超时 比较懒 改了改重复进队的条件~ */ ...
- 洛谷P1066 2^k进制数(题解)(递推版)
https://www.luogu.org/problemnew/show/P1066(题目传送) (题解)https://www.luogu.org/problemnew/solution/P106 ...
- 洛谷1066 2^k进制数
原题链接 大力猜结论竟然猜对了.. 对于一对\(k,w\),我们可以把\(w\)位划分成\(k\)位一段的形式,每一段就是转换成十进制后的一位,这个从题面的解释中应该可以理解. 先不考虑可能多出(即剩 ...
- [洛谷P3332][ZJOI2013]K大数查询
题目大意:有$n$个位置,$m$个操作.操作有两种: $1\;l\;r\;x:$在区间$[l,r]$每个位置加上一个数$x$ $2\;l\;r\;k:$询问$[l,r]$中第$k$大的数是多少. 题解 ...
- [NOIP2006] 提高组 洛谷P1066 2^k进制数
题目描述 设r是个2^k 进制数,并满足以下条件: (1)r至少是个2位的2^k 进制数. (2)作为2^k 进制数,除最后一位外,r的每一位严格小于它右边相邻的那一位. (3)将r转换为2进制数q后 ...
- 洛谷P1138 第k小整数
我偏不用sort Treap好题啊 看到只有一个人写Treap,而且写的不清楚,那我就来详细地写一下,方便新人学习 第(-1)部分:前置知识 二叉查找树:满足左子树的数据都比根节点小,右子树的数据都比 ...
- 洛谷P3332 [ZJOI2013]K大数查询 权值线段树套区间线段树_标记永久化
Code: #include <cstdio> #include <algorithm> #include <string> #include <cstrin ...
- 洛谷P1993 小 K 的农场
题目描述 小 K 在 Minecraft 里面建立很多很多的农场,总共 n 个,以至于他自己都忘记了每个 农场中种植作物的具体数量了,他只记得一些含糊的信息(共 m 个),以下列三种形式描 述: 农场 ...
- 洛谷 P1066 2^k进制数
P1066 2^k进制数 题目描述 设r是个2^k 进制数,并满足以下条件: (1)r至少是个2位的2^k 进制数. (2)作为2^k 进制数,除最后一位外,r的每一位严格小于它右边相邻的那一位. ( ...
随机推荐
- 【Android逆向】破解看雪9月算法破解第一题
1. 安装apk到手机 2. 随意输入账号和密码,点击register,报错crackme1:ERROR 3. 将apk拖入到jadx中进行观察 public native String regist ...
- [BUUCTF][WEB][极客大挑战 2019]BabySQL 1
靶机打开url 界面上显示,它做了更严格的过滤.看来后台是加了什么过滤逻辑 老规矩先尝试时候有sql注入的可能,密码框输入 123' 爆出sql错误信息,说明有注入点 构造万能密码注入 123' or ...
- 用ABP Suite创建Blazor Server的应用程序
这个应用程序我们取名为BlazorOne,意思是集AuthServer.HttpApi Host和Blazor Server3个功能于一体的应用程序.因为ABP Suite支持另外一种模式,是把上述3 ...
- PHP项目&RCE安全&调试&追踪&代码执行&命令执行
常见漏洞关键字 SQL注入:select.insert.update.mysql_query.mysqli等 文件上传:$_FILES.type="file".上传.move_up ...
- Djiango视图层和模型层
Djiango 使用教程 目录 Djiango 使用教程 一. 视图层 1.1 HttpResponse,render,redirect 1.2 JsonResponse 1.3 form表单上传文件 ...
- centos 磁盘满
1.使用命令:df -lk 找到已满磁盘 2.使用命令:du --max-depth=1 -h 查找大文件,删除
- org.jetbrains.idea.maven - com.google.inject.CreationException: Unable to create injector, see the following errors-导入maven项目报错
一.问题由来 最近准备更换Java开发工具,以前是使用Eclipse,现在准备换成号称Java开发神器的IntelliJ IDEA .在同事那里找到安装包后, 安装,导入需要的文件等等,一切都进行得很 ...
- 简单实用算法——位图算法(BitMap)
目录 算法原理 优点和缺点 算法实现(C#) 算法应用 参考文章 算法原理 BitMap的基本思想就是用一个bit位来标记某个元素对应的Value,而Key即是该元素.由于采用了Bit为单位来存储数据 ...
- Java双重循环实现任意字符串中提取数字子串
public class Test2{ public static void main(String[] args) { String s = "211ahn678rh2kkk0731 ...
- 公开的Webservice集锦
备注:以下所有的来自 互联网,版权归原作者所有 股票行情数据 WEB 服务(支持香港.深圳.上海基金.债券和股票:支持多股票同时查询) Endpoint: http://webservice.webx ...