• bzoj2648


    http://www.lydsy.com/JudgeOnline/problem.php?id=2648

    kdtree裸题。。。

    抄板子一边抄对了。。。

    挺好理解的,就是说我们先找出中间的元素,然后小的放左边,大的放右边,这样我们就确定了这个点,然后维度换一下,递归建树,很像splay,其实就是把平面每次一分为二,先横着再竖着。。。

    然后那个get挺神奇的,大概就是估计一下现在这个点距离下一个区域的距离?其实就是优化枚举,减少了很多重复状态。。。

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 1000010, inf = 1 << 29;
    struct data {
        int l, r, d[2], min[2], max[2];
    } t[N];
    int n, m, root, ans, d;
    bool cp(data x, data y) 
    {
        if(x.d[d] != y.d[d]) return x.d[d] < y.d[d];
        return x.d[d ^ 1] < y.d[d ^ 1];
    }
    void update(int k)
    {
        for(int i = 0; i < 2; ++i)
        {
            if(t[k].l) t[k].min[i] = min(t[k].min[i], t[t[k].l].min[i]), t[k].max[i] = max(t[k].max[i], t[t[k].l].max[i]);
            if(t[k].r) t[k].min[i] = min(t[k].min[i], t[t[k].r].min[i]), t[k].max[i] = max(t[k].max[i], t[t[k].r].max[i]);
        }
    } 
    int get(int k, data x)
    {
        int ret = 0;
        for(int i = 0; i < 2; ++i) ret += max(t[k].min[i] - x.d[i], 0) + max(x.d[i] - t[k].max[i], 0);
        return ret;
    }
    int build(int l, int r, int now)
    {
        d = now;
        int mid = (l + r) >> 1;
        nth_element(t + l + 1, t + mid + 1, t + r + 1, cp);
        for(int i = 0; i < 2; ++i) t[mid].min[i] = t[mid].max[i] = t[mid].d[i];
        if(l < mid) t[mid].l = build(l, mid - 1, now ^ 1);
        if(r > mid) t[mid].r = build(mid + 1, r, now ^ 1);
        update(mid); return mid;        
    }
    void insert(int k, int now, data x)
    {
        if(x.d[now] < t[k].d[now]) 
        {
            if(t[k].l) insert(t[k].l, now ^ 1, x);
            else
            {
                t[k].l = ++n;
                for(int i = 0; i < 2; ++i) t[n].max[i] = t[n].min[i] = t[n].d[i] = x.d[i];
            }
        }
        else 
        {
            if(t[k].r) insert(t[k].r, now ^ 1, x);
            else
            {
                t[k].r = ++n;
                for(int i = 0; i < 2; ++i) t[n].max[i] = t[n].min[i] = t[n].d[i] = x.d[i];
            }
        }
        update(k);
    }
    void query(int k, int now, data x)
    {
        int d = abs(t[k].d[0] - x.d[0]) + abs(t[k].d[1] - x.d[1]), dl = inf, dr = inf;
        ans = min(ans, d);
        if(t[k].l) dl = get(t[k].l, x);
        if(t[k].r) dr = get(t[k].r, x);
        if(dl < dr)
        {
            if(dl < ans) query(t[k].l, now ^ 1, x);
            if(dr < ans) query(t[k].r, now ^ 1, x); 
        }
        else
        {
            if(dr < ans) query(t[k].r, now ^ 1, x);
            if(dl < ans) query(t[k].l, now ^ 1, x);
        }
    }
    int main()
    {
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= n; ++i) scanf("%d%d", &t[i].d[0], &t[i].d[1]);
        root = build(1, n, 0);
        while(m--)
        {
            int opt; data x; scanf("%d%d%d", &opt, &x.d[0], &x.d[1]);
            if(opt == 1) insert(root, 0, x);
            if(opt == 2) 
            {
                ans = inf;
                query(root, 0, x);
                printf("%d
    ", ans);
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    整数拆分问题的四种解法
    通配符匹配算法
    grundland去色
    rgb和lab的转换
    .Net library that makes converting between color spaces and comparing colors easy
    彩色图像灰度化论文
    ps图片黑白调整算法
    分数化小数算法
    计算机安全专有名词
    入侵检测
  • 原文地址:https://www.cnblogs.com/19992147orz/p/6880695.html
Copyright © 2020-2023  润新知