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;
    }
  • 相关阅读:
    MongoDB 释放磁盘空间 db.runCommand({repairDatabase: 1 })
    RK 调试笔记
    RK Android7.1 拨号
    RK Android7.1 移植gt9271 TP偏移
    RK Android7.1 定制化 itvbox 盒子Launcher
    RK Android7.1 双屏显示旋转方向
    RK Android7.1 设置 内存条作假
    RK Android7.1 设置 蓝牙 已断开连接
    RK Android7.1 进入Camera2 亮度会增加
    RK 3128 调触摸屏 TP GT9XX
  • 原文地址:https://www.cnblogs.com/yohaha/p/5986327.html
Copyright © 2011-2022 走看看