zoukankan      html  css  js  c++  java
  • K-D Tree

    模板:求平面最近点

    #include<bits/stdc++.h>
    using namespace std;
    const long long N=200010,INF=0x3f3f3f3f3f3f3f3f;
    
    inline void upmx(long long &a,const long long b){if(b>a) a=b;}
    inline void upmn(long long &a,const long long b){if(b<a) a=b;}
    inline void upmn2(long long &a,const long long b,long long id){
        if(b<a) idd=id,a=b;
    }
    
    long long D;
    
    struct nd{
        long long id,l,r,mn[2],mx[2],d[2];
        bool operator<(const nd&a)const{
            return d[D]<a.d[D];
        }
    }t[N],a[N],now;
    long long mn;
    
    inline long long sqr(long long x){
        return x*x;
    }
    
    inline long long getdis1(const nd&a,const nd&b){
        return sqr(a.d[0]-b.d[0])+sqr(a.d[1]-b.d[1]);
    }
    
    inline long long getdis2(nd&a,nd&b){
        long long d1=max(max(b.mn[0]-a.d[0],a.d[0]-b.mx[0]),0ll);
        long long d2=max(max(b.mn[1]-a.d[1],a.d[1]-b.mx[1]),0ll);
        return d1*d1+d2*d2;
    }
    void pushup(long long o){
        long long l=t[o].l,r=t[o].r;
        for(long long i=0;i<2;i++){
            t[o].mn[i]=t[o].d[i],t[o].mx[i]=t[o].d[i];
            if(l) upmn(t[o].mn[i],t[l].mn[i]) , upmx(t[o].mx[i],t[l].mx[i]);
            if(r) upmn(t[o].mn[i],t[r].mn[i]) , upmx(t[o].mx[i],t[r].mx[i]);
        }
    }
    
    long long build(long long L,long long R,long long d){
        D=d;
        long long M=L+R>>1;
        nth_element(a+L,a+M,a+R+1);
        t[M]=a[M];
        if(L<M) t[M].l=build(L,M-1,d^1);
        if(R>M) t[M].r=build(M+1,R,d^1);
        pushup(M);
        return M;
    }
        
    void query(long long o){
        if(!o) return;
        if(now.id!=t[o].id) upmn2(mn,getdis1(now,t[o]),t[o].id);
        long long dl=0,dr=0;
        if(t[o].l) dl=getdis2(now,t[t[o].l]);
        if(t[o].r) dr=getdis2(now,t[t[o].r]);
        if(dl<dr){
            if(dl<mn) query(t[o].l);
            if(dr<mn) query(t[o].r);
        }else{
            if(dr<mn) query(t[o].r);
            if(dl<mn) query(t[o].l);
        }
    }
    
    long long root,n;
    
    void debug_kdtree(){
        long long n;
        scanf("%lld",&n);
        for(long long i=1;i<=n;i++){
            scanf("%lld%lld",&a[i].d[0],&a[i].d[1]);
            a[i].id=i;
        }
        long long root=build(1,n,0);
        for(long long i=1;i<=n;i++){
            mn=INF;
            now=a[i];
            query(root);
    		cout<<mn<<endl;
        }
    }
    
    
    
  • 相关阅读:
    hive日期转换函数2
    hive中的日期转换函数
    Oracle的字符连接函数 concat 和 || 的区别
    Oracle的去重函数 distinct
    Oracle之常用sql
    基于 Consul 的 Docker Swarm 服务发现
    Swift原理
    Mirantis OpenStack 8.0 版本
    vmare虚拟化解决方案
    docker网络解析
  • 原文地址:https://www.cnblogs.com/lsq647vsejgfb/p/9695893.html
Copyright © 2011-2022 走看看