P4357-[CQOI2016]K远点对【K-Dtree】

1|0正题

题目链接:https://www.luogu.com.cn/problem/P4357


1|1题目大意

平面上给出n个点,求第k远的点对距离。


1|2解题思路

K-Dtree的模板题,但是这里只有二维,大概是每次根据一个维度把n个点分成两半像线段树一样丢到下面继续分治的思想来构建一棵树。

那么这样分割出来的每个节点的点分割了自己的矩形范围成了两个子节点的矩形范围。

这题的话我们就先构造出K-Dtree然后记录一下每个节点的矩形范围。

之后开一个小根堆,里面先丢2k0(因为会算重),然后每次找到的一个点对距离如果比堆顶大就要换一个新的进堆就好了。

这样就保证了堆里存的是前2k大的点对了,之后每次用矩形范围判断一下新的答案是否在某个子节点的矩形里面。

理论上为了保证复杂度是需要替罪羊重构的,但是这题数据比较小就好很多。

因为k比较小所以能保证复杂度


1|3code

#include<cstdio> #include<cstring> #include<algorithm> #include<cstdlib> #include<queue> #define ll long long #define pw(x) ((x)*(x)) using namespace std; const ll N=4e5+10,inf=1e18; struct point{ ll x[2]; }w[N],p[N]; ll n,k,cnt,opt,mx[N][2],mi[N][2],ls[N],rs[N]; priority_queue<ll> q; bool cmp(point x,point y) {return x.x[opt]<y.x[opt];} ll gdis(point x,point y) {return pw(x.x[0]-y.x[0])+pw(x.x[1]-y.x[1]);} ll limd(point x,ll y) {return max(pw(x.x[0]-mx[y][0]),pw(x.x[0]-mi[y][0]))+max(pw(x.x[1]-mx[y][1]),pw(x.x[1]-mi[y][1]));} void PushUp(ll x){ ll l=ls[x],r=rs[x]; mx[x][0]=mi[x][0]=w[x].x[0]; mx[x][1]=mi[x][1]=w[x].x[1]; if(l){ for(ll i=0;i<2;i++)mx[x][i]=max(mx[x][i],mx[l][i]); for(ll i=0;i<2;i++)mi[x][i]=min(mi[x][i],mi[l][i]); } if(r){ for(ll i=0;i<2;i++)mx[x][i]=max(mx[x][i],mx[r][i]); for(ll i=0;i<2;i++)mi[x][i]=min(mi[x][i],mi[r][i]); } return; } void Build(ll &x,ll l,ll r,ll z){ if(l>r)return;x=++cnt; ll mid=(l+r)>>1;opt=z; nth_element(p+l,p+mid,p+r+1,cmp); w[x]=p[mid]; Build(ls[x],l,mid-1,z^1); Build(rs[x],mid+1,r,z^1); PushUp(x);return; } void Query(ll x,point v){ if(!x)return; ll dl=-inf,dr=-inf; if(ls[x])dl=limd(v,ls[x]); if(rs[x])dr=limd(v,rs[x]); ll dis=gdis(w[x],v); if(dis>-q.top())q.pop(),q.push(-dis); if(dl>dr){ if(dl>-q.top())Query(ls[x],v); if(dr>-q.top())Query(rs[x],v); } else{ if(dr>-q.top())Query(rs[x],v); if(dl>-q.top())Query(ls[x],v); } return; } signed main() { scanf("%lld%lld",&n,&k); for(ll i=1;i<=n;i++) scanf("%lld%lld",&p[i].x[0],&p[i].x[1]); ll rt;Build(rt,1,n,0); for(ll i=1;i<=2*k;i++)q.push(0); for(ll i=1;i<=n;i++)Query(1,p[i]); printf("%lld\n",-q.top()); }

__EOF__

本文作者QuantAsk
本文链接https://www.cnblogs.com/QuantAsk/p/14279329.html
关于博主:退役OIer,GD划水选手
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   QuantAsk  阅读(110)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示