zoukankan      html  css  js  c++  java
  • [模板] K-D tree

    K-D tree有点像平衡树,但好像又不太像,就是一个来回切的分治建树,然后暴力加A*查询,详情见代码:

    HDU - 2966

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<ctime>
    #include<queue>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    #define duke(i,a,n) for(register int i = a;i <= n;i++)
    #define lv(i,a,n) for(register int i = a;i >= n;i--)
    #define clean(a) memset(a,0,sizeof(a))
    typedef long long ll;
    typedef double db;
    const ll INF = 1e18;
    template <class T>
    void read(T &x)
    {
        char c;
        bool op = 0;
        while(c = getchar(), c < '0' || c > '9')
            if(c == '-') op = 1;
        x = c - '0';
        while(c = getchar(), c >= '0' && c <= '9')
            x = x * 10 + c - '0';
        if(op) x = -x;
    }
    template <class T>
    void write(T x)
    {
        if(x < 0) putchar('-'), x = -x;
        if(x >= 10) write(x / 10);
        putchar('0' + x % 10);
    }
    const int N = 1e5 + 5;
    int dim = 0,n = 0;
    struct node
    {
        int ch[2],id;
        ll d[2],minn[2],maxn[2];
        bool operator < (const node &oth) const
        {
            return d[dim] < oth.d[dim];
        }
    }t[N << 2],a[N],b[N];
    int root,tcnt = 0;
    void push_up(int now)
    {
        for(int i = 0;i < 2;i++)
        {
            if(t[now].ch[0])
            {
                t[now].minn[i] = min(t[now].minn[i],t[t[now].ch[0]].minn[i]);
                t[now].maxn[i] = max(t[now].maxn[i],t[t[now].ch[0]].maxn[i]);
            }
            if(t[now].ch[1])
            {
                t[now].minn[i] = min(t[now].minn[i],t[t[now].ch[1]].minn[i]);
                t[now].maxn[i] = max(t[now].maxn[i],t[t[now].ch[1]].maxn[i]);
            }
        }
    }
    void build(int &now,int d,int l,int r)
    {
        if(l > r) return;
        dim = d;
        int mid = (l + r) >> 1;
        nth_element(a + l,a + mid,a + r + 1);
        t[now = ++ tcnt] = a[mid];t[now].id = a[mid].id;
        t[now].minn[0] = t[now].maxn[0] = t[now].d[0];
        t[now].maxn[1] = t[now].minn[1] = t[now].d[1];
        t[now].ch[0] = t[now].ch[1] = 0;
        build(t[now].ch[0],d ^ 1,l,mid - 1);
        build(t[now].ch[1],d ^ 1,mid + 1,r);
        push_up(now);
    }
    ll ans = INF;
    ll dis(int now,ll *d)
    {
        ll ret = 0;
        for(int i = 0;i < 2;i++)
        {
            ret += (t[now].d[i] - d[i]) * (t[now].d[i] - d[i]);
        }
        return ret;
    }
    ll price(int now,ll *d)
    {
        ll ret = 0;
        for(int i = 0;i < 2;i++)
        {
            if(t[now].maxn[i] < d[i]) ret += (d[i] - t[now].maxn[i]) * (d[i] - t[now].maxn[i]);
            else if(t[now].minn[i] > d[i]) ret += (d[i] - t[now].minn[i]) * (d[i] - t[now].minn[i]);
        }
        return ret;
    }
    void query(int now,int id)
    {
        if(!now) return;
        if(t[now].id ^ id) ans = min(ans,dis(now,b[id].d));
        ll disl = price(t[now].ch[0],b[id].d),disr = price(t[now].ch[1],b[id].d);
        if(disl < ans) query(t[now].ch[0],id);
        if(disr < ans) query(t[now].ch[1],id);
    }
    int T;
    int main()
    {
        read(T);
        while(T--)
        {
            tcnt = 0;
            read(n);
            duke(i,1,n)
            {
                read(a[i].d[0]);read(a[i].d[1]);
                a[i].id = i;
                b[i] = a[i];
            }
            build(root,0,1,n);
            duke(i,1,n)
            {
                ans = INF;
                query(root,i);
                printf("%lld
    ",ans);
            }
        }
        return 0; 
    }
  • 相关阅读:
    HashMap底层实现原理/HashMap与HashTable区别/HashMap与HashSet区别(转)
    JSP语法
    Web开发基础(读书笔记)
    eclispe新导入的文件有个小红叉号(x)的问题
    Vue处理数据,数组更新,但视图无法得到及时更新
    VUE 利用tab切换+同路由跳转传参(check)+vant上拉加载制作订单列表(终)
    适配方案一之:利用rem和less计算制作移动端适配页面
    Git常用命令务忘
    git提交代码步骤笔记
    Vue仿淘宝订单状态的tab切换效果——(但现实中不会用此种方式进行存储数据)
  • 原文地址:https://www.cnblogs.com/DukeLv/p/10289846.html
Copyright © 2011-2022 走看看