zoukankan      html  css  js  c++  java
  • hdu 2966 In case of failure k-d树

    题目链接

    给n个点, 求出每个点到离它最近的点的距离。

    直接建k-d树然后查询就可以  感觉十分神奇...

    明白了算法原理但是感觉代码还不是很懂...

    #include <bits/stdc++.h>
    using namespace std;
    #define pb(x) push_back(x)
    #define ll long long
    #define mk(x, y) make_pair(x, y)
    #define lson l, m, rt<<1
    #define mem(a) memset(a, 0, sizeof(a))
    #define rson m+1, r, rt<<1|1
    #define mem1(a) memset(a, -1, sizeof(a))
    #define mem2(a) memset(a, 0x3f, sizeof(a))
    #define rep(i, n, a) for(int i = a; i<n; i++)
    #define fi first
    #define se second
    typedef complex <double> cmx;
    typedef pair<int, int> pll;
    const double PI = acos(-1.0);
    const double eps = 1e-8;
    const int mod = 1e9+7;
    const int inf = 1061109567;
    const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
    struct node
    {
        int p[2];
        int l, r, idx;
        int operator [] (const int& idx)const
        {
            return p[idx];
        }
    }a[100005];
    int cmpflag, idx[100005];
    ll ans;
    bool cmp(const node& x, const node& y)
    {
        return x[cmpflag] < y[cmpflag];
    }
    int build(int l, int r, int flag)
    {
        int mid = l + r >> 1;
        cmpflag = flag;
        nth_element(a+l, a+mid, a+r+1, cmp);
        idx[a[mid].idx] = mid;
        a[mid].l = (l != mid)?build(l, mid - 1, !flag):0;
        a[mid].r = (r != mid)?build(mid + 1, r, !flag):0;
        return mid;
    }
    ll dis(ll x, ll y = 0)
    {
        return x * x + y * y;
    }
    ll query(int rt, int flag, int x, int y)
    {
        ll tmp = dis(x - a[rt][0], y - a[rt][1]);
        if(tmp) {
            ans = min(ans, tmp);
        }
        if(a[rt].l && a[rt].r) {
            bool d = !flag ? (x <= a[rt][0]) : (y <= a[rt][1]);
            ll dist = !flag ? dis(x - a[rt][0]) : dis(y - a[rt][1]);
            query(d?a[rt].l:a[rt].r, !flag, x, y);
            if(dist < ans) {
                query(!d?a[rt].l:a[rt].r, !flag, x, y);
            }
        } else if(a[rt].l) {
            query(a[rt].l, !flag, x, y);
        } else if(a[rt].r) {
            query(a[rt].r, !flag, x, y);
        }
    }
    int main()
    {
        int t, n;
        cin>>t;
        while(t--) {
            cin>>n;
            for(int i = 1; i <= n; i++) {
                scanf("%d%d", &a[i].p[0], &a[i].p[1]);
                a[i].idx = i;
            }
            int root = build(1, n, 0);
            for(int i = 1; i <= n; i++) {
                ans = 1e18;
                query(root, 0, a[idx[i]][0], a[idx[i]][1]);
                printf("%lld
    ", ans);
            }
        }
        return 0;
    }
  • 相关阅读:
    解决docx4j 变量替换 由于变量存在样式式或空白字符 导致替换失败问题
    redis批量删除key 远程批量删除key
    idea 集成sonarLint检查代码bugs
    mac jmeter 的使用
    tomcat配置管理员-走后门
    终端mysql Operation not permitted错误解决方案
    update使用inner join
    hibernate 三种状态的转换
    数据库中间表插入乱序
    解决https证书验证不通过的问题
  • 原文地址:https://www.cnblogs.com/yohaha/p/5986327.html
Copyright © 2011-2022 走看看