• 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;
        }
    }
    
    
    
  • 相关阅读:
    FreeRTOS相关转载-(朱工的专栏)
    任务相关的API函数-uxTaskGetSystemState
    STM32用FreeRTOS时任务优先级和中断优先级说明
    STM32标准外设库中USE_STDPERIPH_DRIVER, STM32F10X_MD的含义
    C语言变量和函数命名规范
    Java学习笔记-命令模式
    leetcode-Search in Rotated Sorted Array -java
    Java学习笔记-单件模式
    Java学习笔记-问问题?-->静态方法
    TCP滑动控制
  • 原文地址:https://www.cnblogs.com/lsq647vsejgfb/p/9695893.html
Copyright © 2020-2023  润新知