P4357 [CQOI2016]K远点对(KDTree)
又一次产生了KDTree本质就是爆搜的感觉……
大概就类似于p4169,只不过是从最近点对变成了第\(k\)远点对
我们开一个小根堆,里面放\(k\)个元素,起初全为\(0\),然后每一次都把点对的距离和堆顶比较,如果点对距离大于就弹出堆顶并让这个点对入堆,那么最后堆顶就是答案了
于是我们可以枚举每一个点,然后在KDTree上dfs就行了
然后因为每个点对会被枚举两次,所以小根堆的大小实际上要开\(2*k\)
//minamoto
#include<bits/stdc++.h>
#define R register
#define ll long long
#define inf 0x3f3f3f3f
#define fp(i,a,b) for(R int i=a,I=b+1;i<I;++i)
#define fd(i,a,b) for(R int i=a,I=b-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
using namespace std;
char buf[1<<21],*p1=buf,*p2=buf;
inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
ll read(){
R ll res,f=1;R char ch;
while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
return res*f;
}
const int N=1e5+5;
struct node{ll v[2],mn[2],mx[2];int l,r;}tr[N],S;
int n,m,K,rt;priority_queue<ll,vector<ll>,greater<ll> >q;
inline bool operator <(const node &a,const node &b){return a.v[K]<b.v[K];}
void upd(int p){
int l=tr[p].l,r=tr[p].r;
fp(i,0,1){
tr[p].mn[i]=tr[p].mx[i]=tr[p].v[i];
if(l)cmin(tr[p].mn[i],tr[l].mn[i]),cmax(tr[p].mx[i],tr[l].mx[i]);
if(r)cmin(tr[p].mn[i],tr[r].mn[i]),cmax(tr[p].mx[i],tr[r].mx[i]);
}
}
int build(int l,int r,int k){
K=k;int mid=(l+r)>>1;nth_element(tr+l,tr+mid,tr+r+1);
if(l<mid)tr[mid].l=build(l,mid-1,k^1);
if(mid<r)tr[mid].r=build(mid+1,r,k^1);
upd(mid);return mid;
}
inline ll sqr(ll x){return x*x;}
inline ll ck(ll x,ll y,int p){
return max(sqr(tr[p].mn[0]-x),sqr(tr[p].mx[0]-x))+max(sqr(tr[p].mn[1]-y),sqr(tr[p].mx[1]-y));
}
inline ll dis(ll x,ll y,ll xx,ll yy){
return sqr(x-xx)+sqr(y-yy);
}
void query(int p){
ll dl=-inf,dr=-inf,dd=dis(tr[p].v[0],tr[p].v[1],S.v[0],S.v[1]);
if(tr[p].l)dl=ck(S.v[0],S.v[1],tr[p].l);
if(tr[p].r)dr=ck(S.v[0],S.v[1],tr[p].r);
if(dd>q.top())q.pop(),q.push(dd);
if(dl>dr){
if(dl>q.top())query(tr[p].l);
if(dr>q.top())query(tr[p].r);
}else{
if(dr>q.top())query(tr[p].r);
if(dl>q.top())query(tr[p].l);
}
}
int main(){
// freopen("testdata.in","r",stdin);
n=read(),m=read();fp(i,1,n)tr[i].v[0]=read(),tr[i].v[1]=read();
rt=build(1,n,0);fp(i,1,m*2)q.push(0);
fp(i,1,n)S.v[0]=tr[i].v[0],S.v[1]=tr[i].v[1],query(rt);
printf("%lld\n",q.top());return 0;
}
P4357 [CQOI2016]K远点对(KDTree)的更多相关文章
- [BZOJ4520][Cqoi2016]K远点对 kd-tree 优先队列
4520: [Cqoi2016]K远点对 Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 1285 Solved: 708[Submit][Statu ...
- 【BZOJ4520】[Cqoi2016]K远点对 kd-tree+堆
[BZOJ4520][Cqoi2016]K远点对 Description 已知平面内 N 个点的坐标,求欧氏距离下的第 K 远点对. Input 输入文件第一行为用空格隔开的两个整数 N, K.接下来 ...
- [Cqoi2016]K远点对 K-Dtree
4520: [Cqoi2016]K远点对 链接 bzoj 思路 用K-Dtree求点的最远距离. 求的时候顺便维护一个大小为2k的小根堆. 不知道为啥一定会对. 代码 #include <bit ...
- P4357 [CQOI2016]K远点对
题意:给定平面中的 \(n\) 个点,求第 \(K\) 远的点对之间的距离,\(n\leq 1e5,K\leq min(100,\frac{n\times (n-1)}{2})\) 题解:kd-tre ...
- BZOJ 4520: [Cqoi2016]K远点对 KDtree + 估价函数 + 堆
Code: #include<bits/stdc++.h> #define ll long long #define maxn 200000 #define inf 10000000000 ...
- 【BZOJ-4520】K远点对 KD-Tree + 堆
4520: [Cqoi2016]K远点对 Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 490 Solved: 237[Submit][Status ...
- BZOJ 4520: [Cqoi2016]K远点对
4520: [Cqoi2016]K远点对 Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 638 Solved: 340[Submit][Status ...
- [bzoj4520][Cqoi2016]K远点对_KD-Tree_堆
K远点对 bzoj-4520 Cqoi-2016 题目大意:已知平面内 N 个点的坐标,求欧氏距离下的第 K 远点对. 注释:$1\le n\le 10^5$,$1\le k\le 100$,$k\l ...
- BZOJ4520 [Cqoi2016]K远点对
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000作者博客:http://www.cnblogs.com/ljh2000-jump/转 ...
随机推荐
- linux 开机启动脚本或者服务
https://blog.csdn.net/zhuchunyan_aijia/article/details/53811368
- POJ 1661 Help Jimmy【DP】
基础DP,过程想明白了其实也不复杂,从上面的推下面的比倒着推要简单很多.调试了半个多小时..简单dp依然不能快速AC..SAD.. 题目链接: http://poj.org/problem?id=16 ...
- LightOJ1094 - Farthest Nodes in a Tree(树的直径)
http://lightoj.com/volume_showproblem.php?problem=1094 Given a tree (a connected graph with no cycle ...
- Java实验——输出二维数组连续二维子数组的最大和
该算法思路,根据我博客里面一维子数组求和的思路,可以用一个新的二维数组对该二维区域的数组进行求和,例如新的二维数组的第5个位置,就代表从1到5斜对角线的块状区域的和,即1,2,4,5这4个数的和,x个 ...
- IOS开发 Block的学习
苹果公司正在大力推广Block块语法的使用,据说Block会迟早取代一般协议代理的使用. Block最大的作用是函数回调,简化代码. 在ios中,将blocks当成对象来处理,它封装了一段代码,这段代 ...
- 电脑控制手机的另一选择——android vnc server
近来发现的Android上的原生VNC Server,就是说只要手机上安装并运行这个软件,即可实现电脑上查看并控制手机了. 首先是手机端. 1)下载androidvncserver: http://c ...
- [Angular] Refactor Angular Component State Logic into Directives
Allow the base toggle to be a tag (<toggle>) or attribute (<div toggle>). The <toggle ...
- js性能优化之函数节流(分流函数)
函数节流的原理 比如我们在window.onresize事件中要打印当前浏览器窗口的大小,在我们通过拖拽来改变窗口大小时候,打印窗口大小这个工作1s就运行了10次.而实际上我们只需要2次或者3次. 比 ...
- C++ std::tr1::shared_ptr使用说明
1. 介绍 shared_ptr 是通过指针保持某个对象的共享拥有权的智能指针. 若干个 shared_ptr 对象能够拥有同一个对象:最后一个指向该对象的 shared_ptr 被销毁或重置时.该对 ...
- (WPF)附加属性
<Window x:Class="DeepXAML.MainWindow" xmlns="http://schemas.microsoft.com/winfx/20 ...