Time Limit: 30 Sec  Memory Limit: 512 MB

Submit: 588  Solved: 309

[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

【题解】

第K远点对。是说C(N,2)个点对里面。点对之间的距离是第K远的。求这个距离。

我们枚举每个点。然后查看它与其他点的距离。

维护一个1..2*K远的队列。然后不断更新这个队列

(为什么是2*k,想想我们在枚举第一个点的时候,假如和第3个点配对,距离为第2远那么下次再枚举第3个点的时候还会遇到第一个点。又出现了一个第2远的数要加入到队列中。而这两个距离其实是同一个点对的。即排列。考虑其他第1,3,4,..k远的点对也会出现这种情况。我们就把K变成2*K。);

【代码】

#include <cstdio>
#include <algorithm> using namespace std; const int MAX_N = 109000; int n, k,root,now;
long long duilie[300]; struct point
{
long long d[2], mi_n[2], ma_x[2] ;
int l,r;
}; point t[MAX_N],op; void input_data()
{
scanf("%d%d", &n, &k);
for (int i = 1; i <= n; i++)
scanf("%lld%lld", &t[i].d[0], &t[i].d[1]);
} bool cmp(point a, point b)
{
return a.d[now] < b.d[now];
} void up_data(int rt)
{
int l = t[rt].l, r = t[rt].r;
for (int i = 0; i <= 1; i++)
{
if (l)
{
t[rt].ma_x[i] = max(t[rt].ma_x[i], t[l].ma_x[i]);
t[rt].mi_n[i] = min(t[rt].mi_n[i], t[l].mi_n[i]);
}
if (r)
{
t[rt].ma_x[i] = max(t[rt].ma_x[i], t[r].ma_x[i]);
t[rt].mi_n[i] = min(t[rt].mi_n[i], t[r].mi_n[i]);
}
}
} int build(int begin, int end, int fx)
{
int m = (begin + end) >> 1;
now = fx;
nth_element(t + begin, t + m, t + end + 1, cmp);
for (int i = 0; i <= 1; i++)
t[m].ma_x[i] = t[m].mi_n[i] = t[m].d[i];
if (begin < m)
t[m].l = build(begin, m - 1, 1 - fx);
if (m < end)
t[m].r = build(m + 1, end, 1 - fx);
up_data(m);
return m;
} long long sqr(long long x)
{
return x*x;
} long long get_dis(int rt)
{
return sqr(t[rt].d[0] - op.d[0]) + sqr(t[rt].d[1] - op.d[1]);
} long long gujia(int rt)//估价函数
{
long long temp = 0;
for (int i = 0; i <= 1; i++)
temp += max(sqr(t[rt].mi_n[i] - op.d[i]), sqr(t[rt].ma_x[i] - op.d[i]));
return temp;
} void query(int rt)
{
long long dis = get_dis(rt);
int k_th = k;
while (duilie[k_th] <= dis)//找到这个距离在队列中的合适位置。
{
k_th--;
if (!k_th)
break;
}
if (k_th != k)
{
for (int i = k; i >= k_th + 2; i--)
duilie[i] = duilie[i - 1];//这个位置后面的数字往后挪。
duilie[k_th + 1] = dis;
}
int l = t[rt].l, r = t[rt].r;
long long gl = -1,gr = -1;
if (l)
gl = gujia(l);
if (r)
gr = gujia(r);
if (gl < gr)
{
if (gr >= duilie[k])
query(r);
if (gl >= duilie[k])
query(l);
}
else
{
if (gl >= duilie[k])
query(l);
if (gr >= duilie[k])
query(r);
}
} void get_ans()
{
root = build(1, n, 0);
k = k * 2;//直接求2*k远
for (int i = 1; i <= k; i++)//duilie[1..k]分别表示第1,2,3..远。因此它是递减队列。
duilie[i] = 0;
for (int i = 1; i <= n; i++)
{
op.d[0] = t[i].d[0], op.d[1] = t[i].d[1];
query(root);
}
} void output_ans()
{
printf("%lld\n", duilie[k]);
} int main()
{
//freopen("F:\\rush.txt", "r", stdin);
input_data();
get_ans();
output_ans();
return 0;
}

【52.55%】【BZOJ 4520】K远点对的更多相关文章

  1. BZOJ - 4520 K远点对

    题意:已知平面内 N 个点的坐标,求欧氏距离下的第 K 远点对 维护大小为2k最小堆,KD树的估值用前面提到的做法 PS.网上有人估价是使用边界四个点的最值来独立枚举,然而这样写似乎过不了 #incl ...

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

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

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

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

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

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

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

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

  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. 【JZOJ4861】【NOIP2016提高A组集训第7场11.4】推冰块

    题目描述 Dpstr最近迷上了推冰块.冰地是一个n行m列的网格区域,第i行第j列的格子记为(i,j),也就是左上角为(1,1),右下角为(n,m).每个格子可能是冰面.障碍物.减速带三者之一.其中,冰 ...

  2. 洛谷P3455 [POI2007]ZAP-Queries (莫比乌斯反演)

    题意:求$\sum_{i=1}^{a}\sum_{j=1}^{b}[gcd(i,j)==d]$(1<=a,b,d<=50000). 很套路的莫比乌斯反演. $\sum_{i=1}^{n}\ ...

  3. Directx11学习笔记【八】 龙书D3DApp的实现

    原文:Directx11学习笔记[八] 龙书D3DApp的实现 directx11龙书中的初始化程序D3DApp跟我们上次写的初始化程序大体一致,只是包含了计时器的内容,而且使用了深度模板缓冲. D3 ...

  4. shell学习(15)- eval及shell No such file or directory解决办法

    eval可以读取一连串的参数,然后按照参数特性来执行.参数数目不限,彼此之间用分号隔开. eval会对后面的命令进行两遍扫描,如果第一遍扫描后,命令是个普通命令,则执行此命令:如果命令中含有变量的间接 ...

  5. Java练习 SDUT-1171_保留整数

    C语言实验--保留整数 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 输入一个字符串str1,把其中的连续非数字的字符 ...

  6. 实现菜单底部线条沿着 X 轴的值缩放转换scaleX

    效果: 代码: a{padding: 10px 10px; position: relative;} a:before{content: ''; width: 100%; height: 3px; b ...

  7. Intellj IDEA14上用Debug启动项目启动不了:Unable to open debugger port: java.net.SocketException "socket closed"

    详情见上图更清晰 15:11:10 Application Server was not connected before run configuration stop, reason: Unable ...

  8. Jquery FormData文件异步上传 快速指南

    网站中文件的异步上传是个比较麻烦的问题,不过现在通过jquery 可以很容易的解决这个问题: 使用jquery2.1版本,较老版本不支持异步文件上传功能: 表单代码: <form id=&quo ...

  9. C# Brush Color String 互相转换

    using System.Windows.Media; //String转换成Color Color color = (Color)ColorConverter.ConvertFromString(s ...

  10. 队列&优先队列

    1.队列 普通的队列都是先进先出,元素从队尾添加,从队头删除. function queue(){ var arr=[]; this.enqueue=function(item){ arr.push( ...