• 【BZOJ4520】K远点对(KD-Tree)


    【BZOJ4520】K远点对(KD-Tree)

    题面

    BZOJ
    洛谷

    题解

    考虑暴力。
    维护一个大小为(K)的小根堆,然后每次把两个点之间的距离插进去,然后弹出堆顶

    这样子可以用(KD-Tree)优化:
    如果当前平面内可以产生的最远距离小于堆顶,则证明这个平面内的点无法产生贡献
    就不需要计算了

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    using namespace std;
    #define ll long long
    #define RG register
    #define MAX 111111
    #define sqr(x) (1ll*(x)*(x))
    #define cmin(a,b) (a>b?a=b:a)
    #define cmax(a,b) (a<b?a=b:a)
    #define ls (t[o].ch[0])
    #define rs (t[o].ch[1])
    inline int read()
    {
        RG int x=0,t=1;RG char ch=getchar();
        while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
        if(ch=='-')t=-1,ch=getchar();
        while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
        return x*t;
    }
    int D,n,K,rt;
    struct Node{ll d[2];}a[MAX];
    bool operator<(Node a,Node b){return a.d[D]<b.d[D];}
    struct KD_Node{int mn[2],mx[2],ch[2];Node a;}t[MAX];
    priority_queue<ll,vector<ll>,greater<ll> >Q;
    void update(int x,int y)
    {
    	cmin(t[x].mn[0],t[y].mn[0]);cmin(t[x].mn[1],t[y].mn[1]);
    	cmax(t[x].mx[0],t[y].mx[0]);cmax(t[x].mx[1],t[y].mx[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]);
    	t[o].mn[0]=t[o].mx[0]=t[o].a.d[0]=a[o].d[0];
    	t[o].mn[1]=t[o].mx[1]=t[o].a.d[1]=a[o].d[1];
    	if(l<o)ls=Build(l,o-1,d^1),update(o,ls);
    	if(o<r)rs=Build(o+1,r,d^1),update(o,rs);
    	return o;
    }
    ll Dis(Node a,Node b){return sqr(a.d[0]-b.d[0])+sqr(a.d[1]-b.d[1]);}
    ll Dis(Node a,KD_Node b)
    {
    	ll ret=0;
    	ret=max(ret,Dis(a,(Node){b.mn[0],b.mn[1]}));
    	ret=max(ret,Dis(a,(Node){b.mn[0],b.mx[1]}));
    	ret=max(ret,Dis(a,(Node){b.mx[0],b.mn[1]}));
    	ret=max(ret,Dis(a,(Node){b.mx[0],b.mx[1]}));
    	return ret;
    }
    void Query(int o,Node a)
    {
    	ll dis=Dis(a,t[o].a);
    	if(dis>Q.top())Q.pop(),Q.push(dis);
    	if(ls){dis=Dis(a,t[ls]);if(dis>Q.top())Query(ls,a);}
    	if(rs){dis=Dis(a,t[rs]);if(dis>Q.top())Query(rs,a);}
    }
    int main()
    {
    	n=read();K=read();
    	for(int i=1;i<=n;++i)a[i].d[0]=read(),a[i].d[1]=read();
    	rt=Build(1,n,0);
    	for(int i=1;i<=K+K;++i)Q.push(0);
    	for(int i=1;i<=n;++i)Query(rt,a[i]);
    	printf("%lld
    ",Q.top());
    	return 0;
    }
    
    
  • 相关阅读:
    移动web基础
    CSS3
    HTML5新属性
    CSS3初体验之伪元素选择器
    HTML5+CSS3day_01
    CSS补充
    CSS_day02
    CSS_day01
    HTML_day02
    HTML_day01
  • 原文地址:https://www.cnblogs.com/cjyyb/p/9077245.html
Copyright © 2020-2023  润新知