Portal

Description

给出平面上的\(n(n\leq10^5)\)个整点,求在欧几里得距离下第\(k\)远的点对之间的距离。

Solution

k-d树+堆。

用小根堆维护当前找到的第\(k\)大,然后以堆顶元素为基准在k-d树上搜索即可。搜索到一个新值\(d\)时,将其与堆顶元素比较,若大于堆顶元素则弹出堆顶并加入\(d\)。

Code

//「CQOI2016」K 远点对
#include <algorithm>
#include <cstdio>
#include <queue>
typedef long long lint;
using namespace std;
inline char gc()
{
static char now[1<<16],*s,*t;
if(s==t) {t=(s=now)+fread(now,1,1<<16,stdin); if(s==t) return EOF;}
return *s++;
}
inline int read()
{
int x=0; char ch=gc();
while(ch<'0'||'9'<ch) ch=gc();
while('0'<=ch&&ch<='9') x=x*10+ch-'0',ch=gc();
return x;
}
const int N=1e5+10;
const int INF=0x3FFFFFFF;
int n,k;
int rt,ch[N][2];
struct point{int c[2];} pt[N];
struct zone{int c1[2],c2[2];} zn[N];
void update(int p)
{
int ch0=ch[p][0],ch1=ch[p][1];
for(int k=0;k<2;k++)
zn[p].c1[k]=min(pt[p].c[k],min(zn[ch0].c1[k],zn[ch1].c1[k])),
zn[p].c2[k]=max(pt[p].c[k],max(zn[ch0].c2[k],zn[ch1].c2[k]));
}
int D;
bool operator<(point A,point B) {return A.c[D]<B.c[D];}
void bldTr(int &p,int L,int R)
{
if(L>R) return;
int mid=L+R>>1; p=mid;
nth_element(pt+L,pt+mid,pt+R+1);
bldTr(ch[p][0],L,mid-1),bldTr(ch[p][1],mid+1,R);
update(p);
}
priority_queue< lint,vector<lint>,greater<lint> > Q;
point A;
lint dist(point B)
{
lint d=0;
for(int k=0;k<2;k++) d+=1LL*(A.c[k]-B.c[k])*(A.c[k]-B.c[k]);
return d;
}
lint dist(zone Z)
{
if(Z.c1[0]>Z.c2[0]) return 0;
int d[2]; d[0]=d[1]=0;
for(int k=0;k<2;k++) d[k]=max(abs(Z.c1[k]-A.c[k]),abs(Z.c2[k]-A.c[k]));
return 1LL*d[0]*d[0]+1LL*d[1]*d[1];
}
void query(int p)
{
if(!p) return;
lint d=dist(pt[p]);
if(d>Q.top()) Q.pop(),Q.push(d);
lint d0=dist(zn[ch[p][0]]),d1=dist(zn[ch[p][1]]);
if(d0>Q.top()) query(ch[p][0]);
if(d1>Q.top()) query(ch[p][1]);
}
int main()
{
n=read(),k=read();
for(int i=1;i<=n;i++) pt[i].c[0]=read(),pt[i].c[1]=read();
zn[0].c1[0]=zn[0].c1[1]=INF,zn[0].c2[0]=zn[0].c2[1]=-INF;
bldTr(rt,1,n);
for(int i=1;i<=k+k;i++) Q.push(0);
for(int i=1;i<=n;i++) A=pt[i],query(rt);
printf("%d\n",Q.top());
return 0;
}

P.S.

网上好多题解是凸包+旋转卡壳...吓死我了∑(゚Д゚ノ)ノ

LibreOJ2043 - 「CQOI2016」K 远点对的更多相关文章

  1. 「CQOI2016」K 远点对

    /* 考虑暴力 可以n ^ 2枚举点对 然后用一个容量为2k的小根堆来维护第k大 kd-tree呢就是来将这个暴力优化, 每次先找远的并且最远距离不如堆顶的话就不继续找下去 貌似挺难构造数据卡的 */ ...

  2. loj2043 「CQOI2016」K 远点对

    k-d tree 裸题------ #include <algorithm> #include <iostream> #include <cstdio> using ...

  3. LibreOJ2044 - 「CQOI2016」手机号码

    Portal Description 给出两个十一位数\(L,R\),求\([L,R]\)内所有满足以下两个条件的数的个数. 出现至少\(3\)个相邻的相同数字: 不能同时出现\(4\)和\(8\). ...

  4. LoibreOJ 2042. 「CQOI2016」不同的最小割 最小割树 Gomory-Hu tree

    2042. 「CQOI2016」不同的最小割 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据   题目描述 ...

  5. loj #2044. 「CQOI2016」手机号码

    #2044. 「CQOI2016」手机号码 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据   题目描述 ...

  6. LibreOJ2045 - 「CQOI2016」密钥破解

    Portal Description 给出三个正整数\(e,N,c(\leq2^{62})\).已知\(N\)能表示成\(p\cdot q\)的形式,其中\(p,q\)为质数.计算\(r=(p-1)( ...

  7. LibreOJ2042 - 「CQOI2016」不同的最小割

    Portal Description 给出一个给出一个\(n(n\leq850)\)个点\(m(m\leq8500)\)条边的无向图.定义\(cut(s,t)\)等于\(s,t\)的最小割的容量,求在 ...

  8. 「CQOI2016」不同的最小割

    「CQOI2016」不同的最小割 传送门 建出最小割树,把每一个点对的最小割抠出来 \(\text{unique}\) 一下就好了. 参考代码: #include <algorithm> ...

  9. 「ZJOI2013」K大数查询

    「ZJOI2013」K大数查询 传送门 整体二分,修改的时候用线段树代替树状数组即可. 参考代码: #include <cstdio> #define rg register #defin ...

随机推荐

  1. Java设计模式之责任链模式、职责链模式

    本文继续介绍23种设计模式系列之职责链模式.   什么是链 1.链是一系列节点的集合. 2..链的各节点可灵活拆分再重组.   职责链模式 使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间 ...

  2. unbuntu&vim&Kali的各种小知识

    1. vmware workstation 15.0.0 2.ubuntu-18.10-desktop  使用网络地址转换 VMware workstation 1.ctrl+alt 返回  unbu ...

  3. caffe parse_log.sh

    画loss曲线需要用到此shell脚本 #!/bin/bash # Usage parse_log.sh caffe.log # It creates the following two text f ...

  4. Linux运维笔记--第四部

    第四部 3. Linux扩展正则表达式实战 扩展的正则表达式:ERE(主要用于egrep或grep  -E) +      重复一个或一个以上前面的字符. (*是0或多个) ?     重复0个或一个 ...

  5. c++作业:使用函数调用的方法,实现求两个整数中大的数的程序。

    #include <iostream> using namespace std; int main(){ //从键盘接收两个整数,保存在变量num1和num2中 cout<<& ...

  6. Xcode 的expression命令

    expression命令是执行一个表达式,并将表达式返回的结果输出,是LLDB调试命令中最重要的命令,也是我们常用的 p 和 po 命令的 鼻祖. 他主要有2个功能 (1) 执行表达式 举例:改变视图 ...

  7. python入门:最基本的用户登录用户登录,三次错误机会

    #!/usr/bin/env python # -*- coding:utf-8 -*- #用户登录,三次错误机会 """ 导入getpass,给x赋值为1,while真 ...

  8. 如何用纯 CSS 创作一组昂首阔步的圆点

    效果预览 在线演示 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/ejrMKe 可交互视频 ...

  9. Python基础——时间

    导入时间模块 import time 时间戳 print(time.time()) 获取本地时间 print(time.localtime(time.time())) 时间显示格式化 print(ti ...

  10. LOJ 101 最大流(ISAP 模板)

    开long long的最大流 #include<bits/stdc++.h> using namespace std; ;//点数的最大值 ;//边数的最大值 ; struct Edge ...