• [HDU2966]In case of failure——KD树


    In case of failure

            题意:二维平面,求每个点与它最近的点的距离。

            KD树模板。依次选择每个维度进行划分建树。也可以选择方差最大的一维进行划分。随机划分也过了。奇怪的是用定义求方差一直TLE,用D(X) = E(X^2) - E(X)^2 就没有问题,可能是爆精度?最简洁的实现是每个节点直接用(l+r)/2作为节点编号。这里没有用这种方法。代码参考了n+e的ppt。

    #include<bits/stdc++.h>
    typedef long long ll;
    using namespace std;
    #define cmax(a,b) (a<b?a=b:a)
    #define cmin(a,b) (a>b?a=b:a)
    inline ll sqr(ll x){return x*x;}
    const ll INF=3e18;
    const int N=1e5+10;
    
    int D;
    struct Point{int d[2];}p[N],q[N];
    inline bool cmp(Point a,Point b){return a.d[D]<b.d[D];}
    
    //d:每个维度的值,c:子节点,x:x的范围,y:y的范围,
    int d[N][2],c[N][2],x[N][2],y[N][2],tot;
    
    void pushup(int o,int son){
        cmin(x[o][0],x[son][0]);cmax(x[o][1],x[son][1]);
        cmin(y[o][0],y[son][0]);cmax(y[o][1],y[son][1]);
    }
    void build(int &o,int l,int r,int di){//闭区间
        o=++tot;D=di;
        int mid=(l+r)>>1;
        nth_element(p+l,p+mid,p+r+1,cmp);
        d[o][0]=x[o][0]=x[o][1]=p[mid].d[0];
        d[o][1]=y[o][0]=y[o][1]=p[mid].d[1];
        if(l<mid)build(c[o][0],l,mid-1,di^1),pushup(o,c[o][0]);
        if(mid<r)build(c[o][1],mid+1,r,di^1),pushup(o,c[o][1]);
    }
    
    ll ans;
    inline ll eva(Point a,int o){//估计最小欧几里德距离
        return sqr(max(max(x[o][0]-a.d[0],a.d[0]-x[o][1]),0))+
        sqr(max(max(y[o][0]-a.d[1],a.d[1]-y[o][1]),0));
    }
    void query(int o,Point a){
        ll tmp=sqr(a.d[0]-d[o][0])+sqr(a.d[1]-d[o][1]),Min[2];
        if(tmp)cmin(ans,tmp);
        if(c[o][0])cmin(Min[0],eva(a,c[o][0]));else Min[0]=INF;
        if(c[o][1])cmin(Min[1],eva(a,c[o][1]));else Min[1]=INF;
        tmp=Min[0]>Min[1];
        if(Min[tmp]<ans)query(c[o][tmp],a);tmp^=1;
        if(Min[tmp]<ans)query(c[o][tmp],a);
    }
    
    int main(){
        int t,n,o;
        scanf("%d",&t);
        while(t--){
            tot=0;
            scanf("%d",&n);
            for(int i=1;i<=n;++i)
                scanf("%d%d",&p[i].d[0],&p[i].d[1]),q[i]=p[i];
            build(o,1,n,0);
            for(int i=1;i<=n;++i){
                ans=INF;query(o,q[i]);
                printf("%lld
    ",ans);
            }
            for(int i=1;i<=n+5;++i)c[i][0]=c[i][1]=0;
        }
        return 0;
    }
    View Code
  • 相关阅读:
    httpmodule httphandler
    多线程基础
    LiveRTMP之rtmp流flash播放器无法正常播放问题解决(二)
    LiveRTMP CPU占用问题调优(一)
    LiveRTMP之MP4文件进行rtmp点播直播推送(三)
    LiveRTMP推送RTSP视频源进行RTMP直播
    LiveRTMP Android采集AAC流进行RTMP推送
    LiveRTMP 简单高效的RTMP推送库
    mac 终端 常用命令
    Keychain保存数据封装
  • 原文地址:https://www.cnblogs.com/zpengst/p/12790108.html
Copyright © 2020-2023  润新知