zoukankan      html  css  js  c++  java
  • BZOJ 4520 [Cqoi2016]K远点对(KD树)

    【题目链接】 http://www.lydsy.com/JudgeOnline/problem.php?id=4520

    【题目大意】

      求K远点对距离

    【题解】

      修改估价函数为欧式上界估价,对每个点进行dfs,
      因为是无向点对,在小根堆中保留前2k个距离,
      不断更新堆顶元素即可。

    【代码】

    #include <cstdio>
    #include <algorithm>
    #include <queue> 
    using namespace std;
    typedef long long LL;
    const int N=200000;
    inline int read(){
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    struct data{
        LL dis;
        data(){};
        data(const LL&x){dis=x;}
        bool operator <(const data&x)const{return dis>x.dis;}
    }tmp;
    priority_queue<data>q;
    namespace KD_Tree{
        struct Dot{  
            int d[2],mn[2],mx[2],l,r;  
            Dot(){l=r=0;}  
            Dot(int x,int y){d[0]=x;d[1]=y;l=r=0;}  
            int& operator [] (int x){return d[x];}  
        };  
        int D,dcnt=0,pt[N]; 
        Dot T[N],p[N];
        bool operator<(Dot a,Dot b){return a[D]<b[D];}
        inline void umax(int&a,int b){if(a<b)a=b;}
        inline void umin(int&a,int b){if(a>b)a=b;}
        inline bool cmp(int x,int y){return T[x][D]<T[y][D];}
        inline void up(int x){
            T[x].mn[0]=T[x].mx[0]=T[x][0];  
            T[x].mn[1]=T[x].mx[1]=T[x][1]; 
            if(T[x].l){
                umax(T[x].mx[0],T[T[x].l].mx[0]);
                umin(T[x].mn[0],T[T[x].l].mn[0]);   
                umax(T[x].mx[1],T[T[x].l].mx[1]);
                umin(T[x].mn[1],T[T[x].l].mn[1]);
            }
            if(T[x].r){
                umax(T[x].mx[0],T[T[x].r].mx[0]);
                umin(T[x].mn[0],T[T[x].r].mn[0]);
                umax(T[x].mx[1],T[T[x].r].mx[1]);
                umin(T[x].mn[1],T[T[x].r].mn[1]);
            }
        }
        void AddDot(int x,int y){
            ++dcnt; pt[dcnt]=dcnt;
            p[dcnt][0]=x; p[dcnt][1]=y;
        }
        int build(int l,int r,int now){
        	if(l>r)return 0;
            int mid=(l+r)>>1;
            D=now;
            nth_element(p+l,p+mid,p+r+1);
            T[mid]=p[mid];
            for(int i=0;i<2;i++)T[mid].mn[i]=T[mid].mx[i]=T[mid][i];
            if(l<mid)T[mid].l=build(l,mid-1,now^1);
            if(r>mid)T[mid].r=build(mid+1,r,now^1);
            return up(mid),mid;
        }
        LL sqr(LL x){return x*x;}
        inline LL dist(int x,int px,int py){
            LL dis=0;
            if(!x)return 0;
                dis+=max(sqr(T[x].mn[0]-px),sqr(T[x].mx[0]-px));
                dis+=max(sqr(T[x].mn[1]-py),sqr(T[x].mx[1]-py));
                return dis;
            }
        }
        void query(int x,int px,int py){
            if(!x)return;
            LL dl,dr,d0=sqr(T[x][0]-px)+sqr(T[x][1]-py);
            dl=T[x].l?dist(T[x].l,px,py):0;
            dr=T[x].r?dist(T[x].r,px,py):0;
            if(d0>q.top().dis)q.pop(),q.push(data(d0));
            if(dl>dr){
                if(dl>q.top().dis)query(T[x].l,px,py);
                if(dr>q.top().dis)query(T[x].r,px,py);
            }
            else{
                if(dr>q.top().dis)query(T[x].r,px,py);
                if(dl>q.top().dis)query(T[x].l,px,py);
            }
        }
    }
    int n,k;
    int main(){
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++)KD_Tree::AddDot(read(),read());
        int root=KD_Tree::build(1,n,0);
        for(int i=0;i<k+k;i++)q.push(tmp);
        for(int i=1;i<=n;i++)KD_Tree::query(root,KD_Tree::p[i][0],KD_Tree::p[i][1]);
        printf("%lld
    ",q.top().dis);
        return 0;
    }
    
  • 相关阅读:
    openwrt 相关文章
    负载均衡相关文章
    Today's Progress
    Rodrigues formula is beautiful, but uneven to sine and cosine. (zz Berkeley's Page)
    Camera Calibration in detail
    Fundamental Matrix in Epipolar
    Camera Calibration's fx and fy do Cares in SLAM
    FilterEngine::apply
    FilterEngine 类解析——OpenCV图像滤波核心引擎(zz)
    gaussBlur
  • 原文地址:https://www.cnblogs.com/forever97/p/bzoj4520.html
Copyright © 2011-2022 走看看