4520: [Cqoi2016]K远点对

Time Limit: 30 Sec  Memory Limit: 512 MB
Submit: 1285  Solved: 708
[Submit][Status][Discuss]

Description

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

 

Input

输入文件第一行为用空格隔开的两个整数 N, K。接下来 N 行,每行两个整数 X,Y,表示一个点
的坐标。1 < =  N < =  100000, 1 < =  K < =  100, K < =  N*(N−1)/2 , 0 < =  X, Y < 2^31。
 

Output

输出文件第一行为一个整数,表示第 K 远点对的距离的平方(一定是个整数)。

 

Sample Input

10 5
0 0
0 1
1 0
1 1
2 0
2 1
1 2
0 2
3 0
3 1

Sample Output

9

HINT

 

Source

kd-tree可以查询每个点到其他点的距离。

我们求出每两个点间的距离,随后求出第2*k大值即可。

用优先队列维护前2*k大值,在kd-tree上查询并修改即可。

 #include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#define ll long long
#define maxn 100005
using namespace std;
inline int read() {
int x=,f=;char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-;
for(;isdigit(ch);ch=getchar()) x=x*+ch-'';
return x*f;
}
int nowd=,rt,n,k;
struct node {ll d[],mx[],mn[],l,r;}t[maxn];
bool cmp(node t1,node t2) {return t1.d[nowd]<t2.d[nowd];}
priority_queue<ll,vector<ll>,greater<ll> >q;ll cnt=;
void pushup(int x) {
int l=t[x].l,r=t[x].r;
if(l) {
t[x].mx[]=max(t[x].mx[],t[l].mx[]);
t[x].mx[]=max(t[x].mx[],t[l].mx[]);
t[x].mn[]=min(t[x].mn[],t[l].mn[]);
t[x].mn[]=min(t[x].mn[],t[l].mn[]);
}
if(r) {
t[x].mx[]=max(t[x].mx[],t[r].mx[]);
t[x].mx[]=max(t[x].mx[],t[r].mx[]);
t[x].mn[]=min(t[x].mn[],t[r].mn[]);
t[x].mn[]=min(t[x].mn[],t[r].mn[]);
}
}
int build(int l,int r,bool D) {
int mid=l+r>>;nowd=D;
nth_element(t+l,t+mid,t+r+,cmp);
if(l<mid) t[mid].l=build(l,mid-,!D);
if(r>mid) t[mid].r=build(mid+,r,!D);
t[mid].mx[]=t[mid].mn[]=t[mid].d[];
t[mid].mx[]=t[mid].mn[]=t[mid].d[];
pushup(mid);
return mid;
}
ll dis(int x,int y) {return (t[x].d[]-t[y].d[])*(t[x].d[]-t[y].d[])+(t[x].d[]-t[y].d[])*(t[x].d[]-t[y].d[]);}
ll gdis(int x,int y) {
return max((t[x].mn[]-t[y].d[])*(t[x].mn[]-t[y].d[]),(t[x].mx[]-t[y].d[])*(t[x].mx[]-t[y].d[]))+max((t[x].mn[]-t[y].d[])*(t[x].mn[]-t[y].d[]),(t[x].mx[]-t[y].d[])*(t[x].mx[]-t[y].d[]));
}
void query(int x,int y) {
if(!x) return;
ll now=dis(x,y);
if(now>q.top()) {q.pop();q.push(now);}
ll dl=,dr=;
if(t[x].l) dl=gdis(t[x].l,y);if(t[x].r) dr=gdis(t[x].r,y);
if(dl>dr) {
if(dl>q.top()) query(t[x].l,y);
if(dr>q.top()) query(t[x].r,y);
}
else {
if(dr>q.top()) query(t[x].r,y);
if(dl>q.top()) query(t[x].l,y);
}
}
int main() {
n=read();k=read();
for(int i=;i<=n;i++) t[i].d[]=read(),t[i].d[]=read();
rt=build(,n,);
for(int i=;i<=k*;i++) q.push();
for(int i=;i<=n;i++) query(rt,i);
printf("%lld\n",q.top());
}

最新文章

  1. spring mvc DispatcherServlet详解之前传---FrameworkServlet
  2. CookieStore之Cookie的获取与保存
  3. C#日志记录函数
  4. Lambda表达式和匿名内部类(I)
  5. JSP 九个隐含JSP对象
  6. 使用duplicate target database ... from active database复制数据库
  7. 鸟哥的linux私房菜学习记录之程序管理和SElinux初探
  8. iOS - Swift 面向对象语法
  9. FastDFS详解
  10. 算法如功夫——C++ 用递归函数计算n的阶乘n!
  11. 为什么要用深度学习来做个性化推荐 CTR 预估
  12. window下mysql数据备份
  13. c语言贪吃蛇详解4.食物的投放与蛇的变长
  14. CF877F
  15. 大数据小视角2:ORCFile与Parquet,开源圈背后的生意
  16. golang包管理工具glide安装
  17. python的基本数据类型(一)
  18. java基础(十三)-----详解内部类——Java高级开发必须懂的
  19. Fibonacci数列(数列 取模)
  20. Head First Python-Python中与文件相关的操作-读、处理、写

热门文章

  1. webstorm-前端javascript开发神器中文教程和技巧分享(转)
  2. CSS position属性---absolute与relative
  3. 下拉框select chosen被遮盖
  4. Activiti工作流(一)——Activiti Diagram
  5. Python 类和对象-下
  6. [洛谷P2384]最短路
  7. TextView AutoLink, ClikSpan 与长按事件冲突的解决
  8. PowerMock
  9. HDU 多校对抗赛 J Time Zone
  10. bzoj 5099 [POI2018]Pionek 计算几何 极角排序