• kdtree HDU5992


    STL里面的nth_element()函数

    用法:nth_element(first,nth,last)

    int a[maxn];

    nth_element(a,a+k,a+f);

    作用:在a到a+f区间内,使第k位左边的都比它小,右边的都比它大。

    kdtree代码:

    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define INF 0x3f3f3f3f
    #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
    #define pqueue priority_queue
    #define NEW(a,b) memset(a,b,sizeof(a))
    #define lowbit(x) ((x)&(-x))
    const double pi=4.0*atan(1.0);
    const double e=exp(1.0);
    const int maxn=2e5+8;
    typedef long long LL;
    typedef unsigned long long ULL;
    const LL mod=1e9+7;
    const ULL base=1e7+7;
    using namespace std;
    int kdd;
    struct node{
        int id,g[3];
        bool operator<(const node &u)const{
           return g[kdd]<u.g[kdd];
        }
    }kdt[maxn<<2],data[maxn];
    bool flag[maxn<<2];
    LL dis(node a,node b){
        return LL(a.g[0]-b.g[0])*(a.g[0]-b.g[0])+LL(a.g[1]-b.g[1])*(a.g[1]-b.g[1]);
    }
    void build(int l,int r,int rt,int kd){
        kd%=2;
        kdd=kd;
        if(l>r) return ;
        flag[rt]=1;
        int mid=(l+r)>>1;
        nth_element(data+l,data+mid,data+r+1);
        kdt[rt]=data[mid];
        flag[rt<<1]=flag[rt<<1|1]=0;
        if(l<=mid-1){
            build(l,mid,rt<<1,kd+1);
        }
        if(mid+1<=r){
            build(mid+1,r,rt<<1|1,kd+1);
        }
    }
    pair<LL,node> ans;
    void query(int rt,node p,int kd){
        kd%=2;
        pair<LL,node> now={dis(p,kdt[rt]),kdt[rt]};
        int x=rt<<1;
        int y=rt<<1|1;
        if(p.g[kd]>=kdt[rt].g[kd]){
            swap(x,y);
        }
        if(flag[x])
            query(x,p,kd+1);
        bool ff=0;
        if(ans.fi==-1){
            ff=1;
            if(p.g[2]>=kdt[rt].g[2]){
                ans=now;
            }
        }
        else{
            if(p.g[2]>=kdt[rt].g[2]&&(now.fi<ans.fi||now.fi==ans.fi&&now.se.id<ans.se.id)){
                ans=now;
            }
            if(LL(kdt[rt].g[kd]-p.g[kd])*(kdt[rt].g[kd]-p.g[kd])<ans.fi){
                ff=1;
            }
        }
        if(flag[y]&&ff){
            query(y,p,kd+1);
        }
    }
    int main(){
        int t;
        scanf("%d",&t);
        int n,m;
        while(t--){
            scanf("%d%d",&n,&m);
            for(int i=1;i<=n;i++){
                for(int j=0;j<3;j++){
                    scanf("%d",&data[i].g[j]);
                }
                data[i].id=i;
            }
            build(1,n,1,0);
            while(m--){
                node p;
                for(int i=0;i<3;++i){
                    scanf("%d",&p.g[i]);
                }
                ans.fi=-1;
                query(1,p,0);
                printf("%d %d %d
    ",ans.se.g[0],ans.se.g[1],ans.se.g[2]);
            }
        }
    }
  • 相关阅读:
    收藏
    计算矩阵连乘
    关于sublime text
    关于拓扑排序(topologicalsort)
    生成最小树prim算法
    矩阵转置的两种算法
    android wifi热点 socket通信
    AsyncTask异步任务类使用学习
    数据库操作学习
    android 监听短信并发送到服务器
  • 原文地址:https://www.cnblogs.com/Profish/p/10026581.html
Copyright © 2020-2023  润新知