题意:已知平面内 N 个点的坐标,求欧氏距离下的第 K 远点对

维护大小为2k最小堆,KD树的估值用前面提到的做法

PS.网上有人估价是使用边界四个点的最值来独立枚举,然而这样写似乎过不了

#include<bits/stdc++.h>
#define rep(i,j,k) for(register int i=j;i<=k;i++)
#define rrep(i,j,k) for(register int i=j;i>=k;i--)
#define erep(i,u) for(register int i=head[u];~i;i=nxt[i])
#define print(a) printf("%lld",(ll)(a))
#define println(a) printf("%lld\n",(ll)(a))
#define printbk(a) printf("%lld ",(ll)(a))
using namespace std;
const int MAXN = 2e5+11;
const int INF = 0x7fffffff;
typedef long long ll;
ll read(){
ll x=0,f=1;register char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int D;
struct point{
int x[2];
bool operator < (const point &rhs) const{
return x[D]<rhs.x[D];
}
};
struct KD{
int son[MAXN][2];
point p[MAXN],mn[MAXN],mx[MAXN];
int root,ans,tot,n;
priority_queue<ll,vector<ll>,greater<ll> > pq;
void init(int t){
ans=INF; tot=D=0; n=t;
}
void pu(int o){
rep(i,0,1){
if(son[o][i]) rep(j,0,1){
if(mn[son[o][i]].x[j]<mn[o].x[j]) mn[o].x[j]=mn[son[o][i]].x[j];
if(mx[son[o][i]].x[j]>mx[o].x[j]) mx[o].x[j]=mx[son[o][i]].x[j];
}
}
}
int build(int now,int l,int r){
int mid=l+r>>1;
tot++; son[mid][0]=son[mid][1]=0;
D=now;nth_element(p+l,p+mid,p+r+1);//[l,r+1)
mn[mid].x[0]=mx[mid].x[0]=p[mid].x[0];
mn[mid].x[1]=mx[mid].x[1]=p[mid].x[1];
if(l<mid) son[mid][0]=build(now^1,l,mid-1);
if(r>mid) son[mid][1]=build(now^1,mid+1,r);
pu(mid);
return mid;
}
void insert(int &o,int now,point v){
if(!o){
o=++tot;
p[o].x[0]=mn[o].x[0]=mx[o].x[0]=v.x[0];
p[o].x[1]=mn[o].x[1]=mx[o].x[1]=v.x[1];
}else{
insert(son[o][p[o].x[now]<v.x[now]],now^1,v);
pu(o);
}
}
inline ll dis(point a,point b){
return (ll)(a.x[0]-b.x[0])*(a.x[0]-b.x[0])+1ll*(a.x[1]-b.x[1])*(a.x[1]-b.x[1]);
}
inline point mp(int x,int y){
point t;t.x[0]=x;t.x[1]=y;return t;
}
inline ll eva(int o,point &v){
if(!o) return -6666;
ll t1=max(abs(mn[o].x[0]-v.x[0]),abs(mx[o].x[0]-v.x[0]));
ll t2=max(abs(mn[o].x[1]-v.x[1]),abs(mx[o].x[1]-v.x[1]));
return t1*t1+t2*t2;
}
void query(int o,point &v){
if(!o)return;
while(pq.size()>2*n) pq.pop();
ll d1=dis(p[o],v),d2=-6666,d3=-6666;
if(pq.top()<d1){
pq.pop();
pq.push(d1);
}
if(son[o][0]) d2=eva(son[o][0],v);
if(son[o][1]) d3=eva(son[o][1],v);
if(d2>d3){
if(d2>pq.top()) query(son[o][0],v);
if(d3>pq.top()) query(son[o][1],v);
}else{
if(d3>pq.top()) query(son[o][1],v);
if(d2>pq.top()) query(son[o][0],v);
}
}
}kd;
int main(){
int n,k;
while(cin>>n>>k){
kd.init(k);
rep(i,1,n){
kd.p[i].x[0]=read();
kd.p[i].x[1]=read();
}
kd.root=kd.build(0,1,n);
while(!kd.pq.empty()) kd.pq.pop();
rep(i,1,2*k) kd.pq.push(-666);
rep(i,1,n){
kd.query(kd.root,kd.p[i]);
}
println(kd.pq.top());
}
return 0;
}

BZOJ - 4520 K远点对的更多相关文章

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

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

  2. BZOJ 4520 [Cqoi2016]K远点对(KD树)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4520 [题目大意] 求K远点对距离 [题解] 修改估价函数为欧式上界估价,对每个点进行 ...

  3. BZOJ 4520: [Cqoi2016]K远点对(k-d tree)

    Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 1162  Solved: 618[Submit][Status][Discuss] Descripti ...

  4. BZOJ 4520: [Cqoi2016]K远点对 KDtree + 估价函数 + 堆

    Code: #include<bits/stdc++.h> #define ll long long #define maxn 200000 #define inf 10000000000 ...

  5. 【52.55%】【BZOJ 4520】K远点对

    Time Limit: 30 Sec  Memory Limit: 512 MB Submit: 588  Solved: 309 [Submit][Status][Discuss] Descript ...

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

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

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

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

  8. 【bzoj4520】 Cqoi2016—K远点对

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

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

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

随机推荐

  1. 69. Sqrt(x) 求根号再取整

    [抄题]: Implement int sqrt(int x). Compute and return the square root of x, where x is guaranteed to b ...

  2. 如何从Win7上卸载Sql 2008 R2 Express,再重装

    这两天,因工作需要,需要在一台新的机器上,Win7 64位英文操作系统上,安装Sql Server 2008 R2 Express,安装的过程中出现些问题,在查找问题的过程中,考虑重装 Sql Ser ...

  3. Yii2视频

    Yii2 视频分享 需要的小伙伴看过来链接: https://pan.baidu.com/s/1sl4H0RV 密码: nknx  (有问题请留言)

  4. AutoLayout自动布局,NSLayoutConstraint 视图约束使用

    一.方法 NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:<#(id)#> attribut ...

  5. MongoDB整理笔记のCRUD

    添加 下面我们来建立一个test 的集合并写入一些数据.建立两个对象j 和t , 并保存到集合中去.在例子里 “>” 来表示是 shell 输入提示符    > j = { name : ...

  6. C# 的 Task、Thread、ThreadPool 之间有什么异同?

    Thread就是Thread,需要自己调度,适合长跑型的操作. ThreadPool是Thread基础上的一个线程池,目的是减少频繁创建线程的开销.线程很贵,要开新的stack,要增加CPU上下文切换 ...

  7. vs2010 在win8附加进程调试小技巧

    在win8 附加进程居然找不到 我要的是iis 名为HKFlight的web的进程(下面2个勾也勾上了,就是找不到它)(下图是管理员身份运行截图) 解决方法:打开vs2010 用管理员身份打开...其 ...

  8. React + Python 七月小说网 启程(一)

    一.为啥要做这个网站 很久没有写技术相关的博客了,最近几个月忙飞,各种工作,技术根本学不完,很难受. 趁着春节期间,终于有空闲时间做自己爱做的事情了,美滋滋. 热爱技术,热爱小说,于是诞生了个这么玩意 ...

  9. C#多线程编程实战1.2暂停线程(休眠)

    using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...

  10. Win7 WPF程序无法接受外部拖拽

    最近在WPF项目中遇到一个问题.虽然选择了AllowDrop = True,但是还是无法支持从外部拖拽文件到程序,倒是内部拖拽(如从一个列表拖拽到树)和从程序拖拽到外部可以. 解决过程 1.考虑是程序 ...