LibreOJ2043 - 「CQOI2016」K 远点对
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 远点对的更多相关文章
- 「CQOI2016」K 远点对
/* 考虑暴力 可以n ^ 2枚举点对 然后用一个容量为2k的小根堆来维护第k大 kd-tree呢就是来将这个暴力优化, 每次先找远的并且最远距离不如堆顶的话就不继续找下去 貌似挺难构造数据卡的 */ ...
- loj2043 「CQOI2016」K 远点对
k-d tree 裸题------ #include <algorithm> #include <iostream> #include <cstdio> using ...
- LibreOJ2044 - 「CQOI2016」手机号码
Portal Description 给出两个十一位数\(L,R\),求\([L,R]\)内所有满足以下两个条件的数的个数. 出现至少\(3\)个相邻的相同数字: 不能同时出现\(4\)和\(8\). ...
- LoibreOJ 2042. 「CQOI2016」不同的最小割 最小割树 Gomory-Hu tree
2042. 「CQOI2016」不同的最小割 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据 题目描述 ...
- loj #2044. 「CQOI2016」手机号码
#2044. 「CQOI2016」手机号码 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据 题目描述 ...
- LibreOJ2045 - 「CQOI2016」密钥破解
Portal Description 给出三个正整数\(e,N,c(\leq2^{62})\).已知\(N\)能表示成\(p\cdot q\)的形式,其中\(p,q\)为质数.计算\(r=(p-1)( ...
- LibreOJ2042 - 「CQOI2016」不同的最小割
Portal Description 给出一个给出一个\(n(n\leq850)\)个点\(m(m\leq8500)\)条边的无向图.定义\(cut(s,t)\)等于\(s,t\)的最小割的容量,求在 ...
- 「CQOI2016」不同的最小割
「CQOI2016」不同的最小割 传送门 建出最小割树,把每一个点对的最小割抠出来 \(\text{unique}\) 一下就好了. 参考代码: #include <algorithm> ...
- 「ZJOI2013」K大数查询
「ZJOI2013」K大数查询 传送门 整体二分,修改的时候用线段树代替树状数组即可. 参考代码: #include <cstdio> #define rg register #defin ...
随机推荐
- [学习笔记] Markdown语法备忘
Markdown语法总结 标题 # 这是一级标题 ## 这是二级标题 ### 这是三级标题 #### 这是四级标题 ##### 这是五级标题 ###### 这是六级标题 注意#后面要加空格 字体 ** ...
- BCB:Windows消息处理
Windows消息处理 BCB 本文研究了BCB中的消息处理机制,在此基础上提出了处理Windows消息和自定义消息响应的方法和建立动态和静态消息映射的技巧. C++ Builder作为一种RAD方式 ...
- 利用Vue.js实现登录/登出以及JWT认证
JSON Web Token 入门教程:http://www.ruanyifeng.com/blog/2018/07/json_web_token-tutorial.html 后端代码地址:https ...
- c++基本配置属性页
怎么调试一个项目. 需要配置好环境. 在一个release版本的环境中,调试要用release-debug版本,一般不用debug版本. 配置类型一般不变.
- abaqus中的约束
1.tie -绑定约束:作用是将模型的两部分区域绑定在一起,二者之间不发生相对运动,相当于焊在一起. 2.rigid body--刚体约束--使一个模型区域刚体化,这个区域可以是一系列节点,单元等,刚 ...
- windows charles 抓包https请求
charles证书 2.设置host和端口 3.浏览器访问即可抓到https的请求
- 关于mysql中select出数据未排序问题
来自 mysql必知必会
- vi 编辑器命令
插入命令 a append after the cursor A append after the current line i insert before the cursor I insert b ...
- PostgreSQL 全文索引
-- 首先要创建自定义的词典,在不使用停用词文件的情况下创建自定义词典,例如: CREATE TEXT SEARCH DICTIONARY english_stem_nostop ( Template ...
- SQL 与或运算
如果一个字段需要同时包含多个信息点, 最佳的方法是进行位运算,如:1,2,4,8,16 根据与运算进行判断,如一个字段为7,判断2是否存在, 7&2 = 2为ture时,表示存在,反之亦然, ...