题意:已知平面内 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. Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.38/images/json: dial unix /var/run/docker.sock: conne

    使用docker报如下错误信息: Got permission denied while trying to connect to the Docker daemon socket at unix:/ ...

  2. El表达式 (先大致的记录下吧!以后慢慢深入)

    参考:http://blog.csdn.net/eson_15/article/details/51264269 1.获取数据采用 ${标识符} 的形式 request.setAttribute(&q ...

  3. 第一章Python简介

    1.Python shell(Python命令解释器) 如下所示 2.Python的交互模式 如下 3.代码编辑器窗口 在上面的那些指令称为源代码. 4.在python中,缩进是有语法意义的. 在某行 ...

  4. Mybatis——缓存机制

    MyBatis 包含一个非常强大的查询缓存特性,它可以非常方便地配置和定制.缓存可以极大的提升查询效率. MyBatis系统中默认定义了两级缓存. 一级缓存和二级缓存. 1.默认情况下,只有一级缓存( ...

  5. 四则运算(Java) 陈志海 邓宇

    目录 Github项目地址 PSP表格 功能要求 题目 功能(已全部实现) 效能分析 设计实现过程 数值生成 算式生成 问题集生成 设计实现过程 代码说明 测试运行 代码覆盖率 项目小结 Github ...

  6. java类创建时里面成员执行的先后顺序

    静态代码块在类第一次使用的时候执行一次,在构造函数执行之前执行.只要用到类,哪怕new对象(比如只声明变量)也会被执行,且只执行一次.一般用于对类进行初始化. 先执行静态代码块,静态成员(谁在前就先执 ...

  7. delphi 指针 认识

    delphi 指针分为类型指针和无类型指针: 类型指针分为PChar.PInteger.PString等. 无类型指针Pointer. PPChar/PP...为指针的指针 @和Addr一样,为获取变 ...

  8. 搭建自己的git服务器--gogs

    //@desn:搭建自己的git服务器--gogs //@desn:码字不宜,转载请注明出处 //@author:张慧源  <turing_zhy@163.com> //@date:201 ...

  9. U盘安装Ubuntu 12.04成功后系统无法启动的原因及解决办法

    想搭建一个Linux开发环境,选择了ubuntu12.04长期支持版,采用u盘安装(Universal-USB-Installer做的启动),发现安装完成之后,拔掉u盘无法启动,插上u盘之后,可以重启 ...

  10. 关于 href="\\#" 和 return false

    href="\\#"  跳转到本页 return false 相当于不刷新 href="javascript:void(0)"   或者 href=" ...