zoukankan      html  css  js  c++  java
  • bzoj4520 [Cqoi2016]K远点对

    Description

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

    Input

    输入文件第一行为用空格隔开的两个整数 N, K。接下来 N 行,每行两个整数 X,Y,表示一个点
    的坐标。1 < =  N < =  100000, 1 < =  K < =  100, K < =  N*(N−1)/2 , 0 < =  X, Y < 2^31。

    Output

    输出文件第一行为一个整数,表示第 K 远点对的距离的平方(一定是个整数)。

    将所有点建成kd树,用堆维护当前已找到的前k大的点对距离,根据已知的第k大距离距离在kd树上搜索即可

    #include<cstdio>
    #include<queue>
    #include<vector>
    #include<algorithm>
    #include<functional>
    const long long inf=1ll<<62;
    inline void mins(int&a,int b){if(a>b)a=b;}
    inline void maxs(int&a,int b){if(a<b)a=b;}
    inline void maxs(long long&a,long long b){if(a<b)a=b;}
    inline int max(int a){return a>0?a:0;}
    std::priority_queue<long long,std::vector<long long>,std::greater<long long> >mxs;
    int n,k;
    int X[2];
    inline int read(){
        int x=0,c=getchar();
        while(c>57||c<48)c=getchar();
        while(c>47&&c<58)x=x*10+c-48,c=getchar();
        return x;
    }
    inline long long dis(long long x,long long y){
        return x*x+y*y;
    }
    inline void upds(long long x){
        if(x<mxs.top())return;
        mxs.pop();
        mxs.push(x);
    }
    struct node{
        int x[2],mn[2],mx[2];
        node*c[2],*f;
        inline void set(int x1,int x2){
            x[0]=mn[0]=mx[0]=x1;
            x[1]=mn[1]=mx[1]=x2;
        }
        inline void upd(){
            for(int i=0;i<2;i++)if(c[i]){
                for(int j=0;j<2;j++){
                    mins(mn[j],c[i]->mn[j]);
                    maxs(mx[j],c[i]->mx[j]);
                }
            }
        }
        inline long long maxv(){
            if(!this)return -1;
            return dis(max(X[0]-mn[0])|max(mx[0]-X[0]),max(X[1]-mn[1])|max(mx[1]-X[1]));
        }
        void getmax(){
            long long a1=-1,a2=-1;
            upds(dis(x[0]-X[0],x[1]-X[1]));
            maxs(a1,c[0]->maxv());
            maxs(a2,c[1]->maxv());
            if(a1>a2){
                if(a1>mxs.top())c[0]->getmax();
                if(a2>mxs.top())c[1]->getmax();
            }else{
                if(a2>mxs.top())c[1]->getmax();
                if(a1>mxs.top())c[0]->getmax();
            }
        }
    }ns[100005],*rt;
    int dx=0;
    inline bool operator<(const node&a,const node&b){
        if(a.x[dx]!=b.x[dx])return a.x[dx]<b.x[dx];
        return a.x[dx^1]<b.x[dx^1];
    }
    node*build(node*l,node*r){
        if(l==r)return 0;
        node*m=l+(r-l>>1);
        std::nth_element(l,m,r);
        dx^=1;
        m->c[0]=build(l,m);
        m->c[1]=build(m+1,r);
        m->upd();
        dx^=1;
        return m;
    }
    int main(){
        n=read();k=read()*2;
        for(int i=0;i<k;i++)mxs.push(0);
        for(int i=0;i<n;i++)ns[i].set(read(),read());
        rt=build(ns,ns+n);
        for(int i=0;i<n;i++){
            X[0]=ns[i].x[0];
            X[1]=ns[i].x[1];
            rt->getmax();
        }
        printf("%lld",mxs.top());
        return 0;
    } 

    复杂度不易计算但实际运行效果很好

  • 相关阅读:
    系统UINavigationController使用相关参考
    iOS工程集成支付宝错误Undefined symbols for architecture armv7
    Xcode工程使用CocoaPods管理第三方库新建工程时出现错误
    Xcode报错:“Your build settings specify a provisioning profile with the UUID..... however, no such provisioning profile was found”
    iOS开发问题之Could not instantiate class named NSLayoutConstraint
    UICollectionView使用相关博文链接
    UIRefreshControl的使用
    iOS沙盒路径的查看和使用
    【汇总】涉及iOS&iPhone开发相关文章汇总
    【汇总】iOS开发及Xcode使用中遇到的一些报错问题汇总
  • 原文地址:https://www.cnblogs.com/ccz181078/p/5399680.html
Copyright © 2011-2022 走看看