• K-DTree学习


    应用于K维数据的快速查找,比如横坐标,纵坐标,价格……,本模板以16青岛区域赛K题为例 —— 三维K - D Tree 模板
    我们应该都见过平衡树吧,那就是1-D树,变成k维之后,我们连续分割1 - k维,然后继续分割,实现快速查找,画图的时候就能够理解这个数据结构了
    n个旅馆 x,y,csot
    m个用户 x,y,limitcost
    问你每个用户在可以接受的价格内距离最近的旅馆是哪个
    
    #define deep 3 // K-D树的维度
    #define inf (1e18) //用ll防止开根号,造成浮点误差
    using namespace std;
    typedef long long ll;
    const int maxn = 2e5+2e3;
    int retid;//最优的旅馆选择编号
    ll ans;//判断距离最小值
    int loc;//当前进行的维度
    int n,m;//n个旅馆,m个顾客
    struct node{
        int id;
        int data[deep];
        //对各个维度都从小到大排序
        bool operator < (const node &b) const{
            if(data[loc] < b.data[loc])
                return 1;
            return 0;
        }
    }P[maxn],tmp[maxn],Now,Aim;//P数组排序,tmp数组副本作为输出
    void creat_KDtree(int l,int r,int flor){
        if(l >= r){
            return;
        }
        int mid = (l + r) >> 1;
        loc = flor % deep;
    nth_element(P+l,P+mid,P+r+1);
    /*把p+mid元素放在中间位置,使其左边元素比它小,右边比它大
    nth_element(first,nth,last)
    first,last 第一个和最后一个迭代器,也可以直接用数组的位置。
    nth,要定位的第n个元素,能对它进行随机访问.
    将第n_th元素放到它该放的位置上,左边元素都小于它,右边元素都大于它.*/
        creat_KDtree(l,mid-1,flor+1);
        creat_KDtree(mid+1,r,flor+1);
    }
    void judge(int x)//根据题意的判断函数{
        Now = P[x];
        if(Now.data[2] > Aim.data[2])
            return;
        ll dis = (Now.data[0] - Aim.data[0]) * (Now.data[0] - Aim.data[0]) + (Now.data[1] - Aim.data[1]) * (Now.data[1] - Aim.data[1]);
        if(dis < ans || dis == ans && Now.id < retid){
            ans = dis;
            retid = Now.id;
        }
    }
    void Find(int l,int r,int flor)//也是根据题意来写{
        loc = flor % deep;
        if(l >= r){
            if(l == r)
                judge(l);
            return;
        }
        int mid = (l + r) >> 1;
        judge(mid);
        Now = P[mid];
        if(loc == 2){
            if(Now.data[loc] >= Aim.data[loc])
                Find(l,mid-1,flor+1);
            else{
                Find(l,mid-1,flor+1);
                Find(mid+1,r,flor+1);
            }
        }
        else{
            int len = Now.data[loc] - Aim.data[loc];
            if(len >= 0){
                Find(l,mid-1,flor+1);
                if(((ll)len * len) < ans){
                    Find(mid+1,r,flor+1);
                }
            }
            else{
                Find(mid+1,r,flor+1);
                if(((ll)len * len) < ans){
                    Find(l,mid-1,flor+1);
                }
            }
        }
    }
    
  • 相关阅读:
    搭建ARL资产安全灯塔
    免杀技术发展史
    米酷CMS 7.0.4代码审计
    腾讯安全实习 应用运维安全面试
    Docker部署CTF综合性靶场,定时刷新环境
    西湖论剑2020MISC-Yusa_yyds
    (转)马云炮轰银行监管的解读
    ATT&CK 实战
    Docker环境复现利用Redis未授权访问漏洞 >> 批量扫描检测利用
    修改CH340芯片信息
  • 原文地址:https://www.cnblogs.com/DF-yimeng/p/9757291.html
Copyright © 2020-2023  润新知