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

 

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

 

【题目大意】

  求K远点对距离

 

【题解】

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

 

【代码】

#include 
#include 
#include  
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_queueq;
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)a=b;}
    inline bool cmp(int x,int y){return T[x][D]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(lmid)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

 

转载于:https://www.cnblogs.com/forever97/p/bzoj4520.html

你可能感兴趣的:(BZOJ 4520 [Cqoi2016]K远点对(KD树))