[CQOI2016]K远点对(KD-Tree)

Posted hfctf0210

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[CQOI2016]K远点对(KD-Tree)相关的知识,希望对你有一定的参考价值。

暴力的做法应该是这样的,维护大小为k的堆,每次插入两点间距离并弹出堆顶。

然后这个做法显然是可以KD-Tree优化的,建立KD-Tree,然后如果该平面内最远点小于堆顶,则直接退出。就当做是复习很久没做的KD-Tree了。

不过有一个细节要注意,求最远点对,(1,2)->(2,1)算一对,所以堆的大小应该是2*k

技术图片
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+7;
struct pointll d[2];a[N];
struct nodeint mn[2],mx[2],lc,rc;point a;t[N];
priority_queue<ll,vector<ll>,greater<ll> >q;
int n,m,rt,D;
bool operator<(point a,point b)return a.d[D]<b.d[D];
void pushup(int x,int y)

    t[x].mn[0]=min(t[x].mn[0],t[y].mn[0]);
    t[x].mn[1]=min(t[x].mn[1],t[y].mn[1]);
    t[x].mx[0]=max(t[x].mx[0],t[y].mx[0]);
    t[x].mx[1]=max(t[x].mx[1],t[y].mx[1]);

void build(int&k,int l,int r,int d)

    k=0;
    if(l>r)return;
    D=d;
    int mid=l+r>>1;
    nth_element(a+l,a+mid,a+r+1);
    k=mid;
    t[k].mn[0]=t[k].mx[0]=t[k].a.d[0]=a[k].d[0];
    t[k].mn[1]=t[k].mx[1]=t[k].a.d[1]=a[k].d[1];
    build(t[k].lc,l,mid-1,d^1);
    if(t[k].lc)pushup(k,t[k].lc);
    build(t[k].rc,mid+1,r,d^1);
    if(t[k].rc)pushup(k,t[k].rc);

ll getdis(point a,point b)
return(a.d[0]-b.d[0])*(a.d[0]-b.d[0])+(a.d[1]-b.d[1])*(a.d[1]-b.d[1]);
ll getdis2(point a,node b)

    ll ret=0;
    ret=max(ret,getdis(a,(point)b.mn[0],b.mn[1]));
    ret=max(ret,getdis(a,(point)b.mn[0],b.mx[1]));
    ret=max(ret,getdis(a,(point)b.mx[0],b.mn[1]));
    ret=max(ret,getdis(a,(point)b.mx[0],b.mx[1]));
    return ret;

void query(int k,point a)

    ll dis=getdis(a,t[k].a);
    if(dis>q.top())q.pop(),q.push(dis);
    if(t[k].lc)
    
        dis=getdis2(a,t[t[k].lc]);
        if(dis>q.top())query(t[k].lc,a);
    
    if(t[k].rc)
    
        dis=getdis2(a,t[t[k].rc]);
        if(dis>q.top())query(t[k].rc,a);
    

int main()

    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)scanf("%lld%lld",&a[i].d[0],&a[i].d[1]);
    build(rt,1,n,0);
    for(int i=1;i<=m*2;i++)q.push(0);
    for(int i=1;i<=n;i++)query(rt,a[i]);
    printf("%lld",q.top());
View Code

 

以上是关于[CQOI2016]K远点对(KD-Tree)的主要内容,如果未能解决你的问题,请参考以下文章

bzoj4520[Cqoi2016]K远点对 KD-tree+堆

BZOJ-4520K远点对 KD-Tree + 堆

bzoj4520CQOI2016K远点对

LuoguP4357 [CQOI2016]K远点对

「CQOI2016」K 远点对

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