【52.55%】【BZOJ 4520】K远点对
Time Limit: 30 Sec Memory Limit: 512 MB
Submit: 588 Solved: 309
[Submit][Status][Discuss]
Description
已知平面内 N 个点的坐标,求欧氏距离下的第 K 远点对。
Input
Output
输出文件第一行为一个整数,表示第 K 远点对的距离的平方(一定是个整数)。
Sample Input
0 0
0 1
1 0
1 1
2 0
2 1
1 2
0 2
3 0
3 1
Sample Output
【题解】
第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远点对的更多相关文章
- BZOJ - 4520 K远点对
题意:已知平面内 N 个点的坐标,求欧氏距离下的第 K 远点对 维护大小为2k最小堆,KD树的估值用前面提到的做法 PS.网上有人估价是使用边界四个点的最值来独立枚举,然而这样写似乎过不了 #incl ...
- BZOJ 4520: [Cqoi2016]K远点对
4520: [Cqoi2016]K远点对 Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 638 Solved: 340[Submit][Status ...
- BZOJ 4520 [Cqoi2016]K远点对(KD树)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4520 [题目大意] 求K远点对距离 [题解] 修改估价函数为欧式上界估价,对每个点进行 ...
- BZOJ 4520: [Cqoi2016]K远点对(k-d tree)
Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 1162 Solved: 618[Submit][Status][Discuss] Descripti ...
- BZOJ 4520: [Cqoi2016]K远点对 KDtree + 估价函数 + 堆
Code: #include<bits/stdc++.h> #define ll long long #define maxn 200000 #define inf 10000000000 ...
- [Cqoi2016]K远点对 K-Dtree
4520: [Cqoi2016]K远点对 链接 bzoj 思路 用K-Dtree求点的最远距离. 求的时候顺便维护一个大小为2k的小根堆. 不知道为啥一定会对. 代码 #include <bit ...
- 【BZOJ-4520】K远点对 KD-Tree + 堆
4520: [Cqoi2016]K远点对 Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 490 Solved: 237[Submit][Status ...
- 【bzoj4520】 Cqoi2016—K远点对
http://www.lydsy.com/JudgeOnline/problem.php?id=4520 (题目链接) 题意 求平面内第K远点对的距离. Solution 左转题解:jump 细节 刚 ...
- 【BZOJ4520】K远点对(KD-Tree)
[BZOJ4520]K远点对(KD-Tree) 题面 BZOJ 洛谷 题解 考虑暴力. 维护一个大小为\(K\)的小根堆,然后每次把两个点之间的距离插进去,然后弹出堆顶 这样子可以用\(KD-Tree ...
随机推荐
- swiper踩过的哪些坑
最近,苦恼于各种轮播的需求,每个自己都要自己写,写的挺烦的.终于,在网上发现了swiper插件,发现还是挺实用的,但其中还是踩过了不少的坑,其中有不少都是很简单的问题,但到发现的时候都是花了不少时间, ...
- List容器案例
案例讲解 迭代模式 不暴露集合的内部结构,又让外部访问集合中的数据 package com.day1; public interface Iterator <T>{ public bool ...
- 小爬爬4:selenium操作
1.selenium是什么? selenium: - 概念:是一个基于浏览器自动化的模块. - 和爬虫之间的关联? - 帮我我们便捷的爬取到页面中动态加载出来的数据 - 实现模拟登陆 - 基本使用流程 ...
- 一维数组的求平均成绩 Day06
package com.sxt.arraytest1; /* * 求班里学生的平均成绩,以及成绩的综合 输出每个同学的成绩 */ import java.util.Arrays; import jav ...
- 基本的Sql编写注意事项
基本的Sql编写注意事项 尽量少用IN操作符,基本上所有的IN操作符都可以用EXISTS代替. 不用NOT IN操作符,可以用NOT EXISTS或者外连接+替代. Oracle在执行IN子查询时,首 ...
- Java练习 SDUT-1255_小明A+B
小明A+B Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 小明今年3岁了, 现在他已经能够认识100以内的非负整数, ...
- 阿里云IPv6 DDoS防御被工信部认定为“网络安全技术应用试点示范项目”
近日,阿里云数据中心骨干网IPv6 DDoS网络安全防御被工业和信息化部认定为“网络安全技术应用试点示范项目”,本次评选由工业和信息部网络安全管理局发起,从实用性.创新性.先进性.可推广性等维度展 ...
- linux下修改gcc编译器版本
可以使用如下命令行来让 gcc 选择不同的 C++ 版本: g++ -std=c++11 main.cpp 在你的系统中,由于编译器或是编译器设定上的差别,操作也许有所不同.
- 让 AE 输出 MPEG
最近在做视频后期处理,但是我发现 AE 的文件都很大,大概一个 10 分钟视频 10G ,所以有什么办法让他输出的文件变小?一个方法是使用 MPEG 输出. 本文告诉大家如何让 AE 输出 MPEG ...
- H3C 命令行帮助特性(续)