• 初学kd树


    一开始不会kd树的时候,感觉kd树一定很神,学了kd树发现kd树挺好写。

    kd树的每个节点有一个分割超平面,我是以深度%维数作为当前这一维的分割,比较时对于当前节点就比较这一维。

    附上模板代码,求平面第k近距离(kd树裸题)

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<queue>
     6 #include<cmath>
     7 using namespace std;
     8 #define maxn 100020
     9 #define inf 0x3f3f3f3f3f3f3fll
    10 
    11 int now;
    12 typedef long long ll;
    13 struct point{
    14     int x[2];
    15     bool operator < (point a)const{
    16         return x[now] < a.x[now];
    17     }
    18 }a[maxn];
    19 priority_queue <ll> heap;
    20 int n,k,id;
    21 ll curd;
    22 
    23 void build(int l,int r,int dep){
    24     if ( l > r ) return;
    25     now = dep % 2;
    26     int mid = (l + r) >> 1;
    27     nth_element(a + l,a + mid,a + r + 1);
    28     build(l,mid - 1,dep + 1);
    29     build(mid + 1,r,dep + 1);
    30 }
    31 inline ll sqr(int x){ return (ll)x * x; }
    32 inline ll dis(int x1,int x2,int y1,int    y2){
    33     return sqr(x1 - x2) + sqr(y1 - y2);
    34 }
    35 void query(point p,int l,int r,int dep){
    36     if ( l > r ) return;
    37     now = dep % 2;
    38     int mid = (l + r) >> 1;
    39     ll tmp = dis(p.x[0],a[mid].x[0],p.x[1],a[mid].x[1]);
    40     if ( mid > id ){
    41         if ( heap.size() < k ) heap.push(tmp);
    42         else if ( heap.top() > tmp ){ heap.pop(); heap.push(tmp);}
    43     }
    44     if ( l == r ) return;
    45     if ( p.x[now] > a[mid].x[now] ){
    46            query(p,mid + 1,r,dep + 1);
    47         now = dep % 2;
    48         if ( heap.size() < k || heap.top() >= sqr(p.x[now] - a[mid].x[now]) ) query(p,l,mid - 1,dep + 1);
    49     }
    50     else{
    51         query(p,l,mid - 1,dep + 1);
    52         now = dep % 2;
    53         if ( heap.size() < k || heap.top() >= sqr(p.x[now] - a[mid].x[now]) ) query(p,mid + 1,r,dep + 1);
    54     }
    55 }
    56 int main(){
    57     freopen("star.in","r",stdin);
    58     freopen("star.out","w",stdout);
    59     scanf("%d %d",&n,&k);
    60     for (int i = 1 ; i <= n ; i++){
    61         scanf("%d %d",&a[i].x[0],&a[i].x[1]);
    62     }
    63     build(1,n,1);
    64     for (int i = 1 ; i <= n ; i++){
    65         id = i;
    66         query(a[i],1,n,1);
    67     }
    68     printf("%lld
    ",heap.top());
    69     return 0;
    70 }

    以后多学习kd树的应用,kd树模型可以应用的题的类型。

  • 相关阅读:
    [LeetCode] Dungeon Game
    [LeetCode] Maximal Rectangle
    [LeetCode] Scramble String -- 三维动态规划的范例
    [LeetCode] Palindrome Partitioning II
    [LeetCode] Palindrome Partitioning
    [LeetCode] Interleaving String
    [LeetCode] Longest Valid Parentheses -- 挂动态规划羊头卖stack的狗肉
    JPA将查询结果转换为DTO对象
    EOS签名R值过大导致报错"is_canonical( c ): signature is not canonical"
    比特币中P2SH(pay-to-script-hash)多重签名的锁定脚本和解锁脚本
  • 原文地址:https://www.cnblogs.com/zqq123/p/5342514.html
Copyright © 2020-2023  润新知