zoukankan      html  css  js  c++  java
  • 洛谷4357 & BZOJ4520:[CQOI2016]K远点对——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4520

    https://www.luogu.com.cn/problem/P4357

    已知平面内 N 个点的坐标,求欧氏距离下的第 K 远点对。

    KDTREE板子题?

    开个堆维护前2k个最远值(因为我们之后运算的时候每个点对肯定会被算两次,所以我们最终求得第2k最远值才是答案)

    就拿每个点在KDTREE上走一圈就好了……

    剩余的看代码吧……(其实板子代码从某PPT里抄的怕不是看起来会非常熟悉)

    #include<cmath>
    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int K=2;
    const int N=1e5+5;
    const ll INF=1e18;
    inline int read(){
        int X=0,w=0;char ch=0;
        while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
        while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
        return w?-X:X;
    }
    int D,n,k,root;
    struct Point{
        int d[K];
        bool operator <(const Point &a)const{
            return d[D]<a.d[D];
        }
    }a[N];
    struct KDTREE{
        int d[K],s[2],x[2],y[2];
    }tr[N];
    priority_queue<ll,vector<ll>,greater<ll> >q;
    #define ls tr[o].s[0]
    #define rs tr[o].s[1]
    #define cmax(a,b) (a<b?a=b:a)
    #define cmin(a,b) (a>b?a=b:a)
    void upd(int f,int x){
        cmin(tr[f].x[0],tr[x].x[0]),cmax(tr[f].x[1],tr[x].x[1]);
        cmin(tr[f].y[0],tr[x].y[0]),cmax(tr[f].y[1],tr[x].y[1]);
    }
    int build(int l,int r,int d){
        D=d;int o=(l+r)>>1;
        nth_element(a+l,a+o,a+r+1);
        tr[o].d[0]=tr[o].x[0]=tr[o].x[1]=a[o].d[0];
        tr[o].d[1]=tr[o].y[0]=tr[o].y[1]=a[o].d[1];
        if(l<o)ls=build(l,o-1,d^1),upd(o,ls);
        if(o<r)rs=build(o+1,r,d^1),upd(o,rs);
        return o;
    }
    inline ll sqr(ll x){return x*x;}
    inline ll h(int o,Point p){
        return max(sqr(p.d[0]-tr[o].x[0]),sqr(p.d[0]-tr[o].x[1]))
                +max(sqr(p.d[1]-tr[o].y[0]),sqr(p.d[1]-tr[o].y[1]));
    }
    void query(int o,Point p){
        ll tmp=sqr(tr[o].d[0]-p.d[0])+sqr(tr[o].d[1]-p.d[1]),d[2];
        if(ls)d[0]=h(ls,p);else d[0]=-INF;
        if(rs)d[1]=h(rs,p);else d[1]=-INF;
        if(q.top()<tmp){q.pop();q.push(tmp);}
        int op=d[0]<=d[1];
        if(q.top()<d[op])query(tr[o].s[op],p);op^=1;
        if(q.top()<d[op])query(tr[o].s[op],p);
    }
    int main(){
        n=read(),k=read();
        for(int i=1;i<=n;i++){
            a[i].d[0]=read(),a[i].d[1]=read();
        }
        root=build(1,n,0);
        for(int i=1;i<=2*k;i++)q.push(0);
        for(int i=1;i<=n;i++)query(root,a[i]);
        printf("%lld
    ",q.top());
        return 0;
    }

    +++++++++++++++++++++++++++++++++++++++++++

     +本文作者:luyouqi233。               +

     +欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

    +++++++++++++++++++++++++++++++++++++++++++

  • 相关阅读:
    HTML
    python io
    python 线程进程
    python socket
    python 面向对象2
    python 面向对象
    python hashlib模块
    python configparser模块
    python logging模块
    数组去重方法汇总
  • 原文地址:https://www.cnblogs.com/luyouqi233/p/12284132.html
Copyright © 2011-2022 走看看