zoukankan      html  css  js  c++  java
  • 【BZOJ-2648&2716】SJY摆棋子&天使玩偶 KD Tree

    2648: SJY摆棋子

    Time Limit: 20 Sec  Memory Limit: 128 MB
    Submit: 2459  Solved: 834
    [Submit][Status][Discuss]

    Description

    这天,SJY显得无聊。在家自己玩。在一个棋盘上,有N个黑色棋子。他每次要么放到棋盘上一个黑色棋子,要么放上一个白色棋子,如果是白色棋子,他会找出距离这个白色棋子最近的黑色棋子。此处的距离是 曼哈顿距离 即(|x1-x2|+|y1-y2|) 。现在给出N<=500000个初始棋子。和M<=500000个操作。对于每个白色棋子,输出距离这个白色棋子最近的黑色棋子的距离。同一个格子可能有多个棋子。

    Input

    第一行两个数 N M
    以后M行,每行3个数 t x y
    如果t=1 那么放下一个黑色棋子
    如果t=2 那么放下一个白色棋子

    Output

    对于每个T=2 输出一个最小距离

    Sample Input

    2 3
    1 1
    2 3
    2 1 2
    1 3 3
    2 4 2

    Sample Output

    1
    2

    HINT

    kdtree可以过

    Source

    鸣谢 孙嘉裕

    2716: [Violet 3]天使玩偶

    Time Limit: 80 Sec  Memory Limit: 128 MB
    Submit: 1098  Solved: 485
    [Submit][Status][Discuss]

    Description

    Input

    Output

    Sample Input

    100 100
    
    81 23
    
    27 16
    
    52 58
    
    44 24
    
    25 95
    
    34 2
    
    96 25
    
    8 14
    
    97 50
    
    97 18
    
    64 3
    
    47 22
    
    55 28
    
    89 37
    
    75 45
    
    67 22
    
    90 8
    
    65 45
    
    68 93
    
    87 8
    
    61 45
    
    69 72
    
    38 57
    
    58 76
    
    45 34
    
    88 54
    
    27 8
    
    35 34
    
    70 81
    
    25 24
    
    97 97
    
    4 43
    
    39 38
    
    82 68
    
    27 58
    
    2 21
    
    92 88
    
    96 70
    
    97 29
    
    14 53
    
    6 42
    
    1 2
    
    35 84
    
    64 88
    
    63 57
    
    53 40
    
    82 59
    
    49 56
    
    75 72
    
    29 30
    
    50 1
    
    40 83
    
    52 94
    
    22 35
    
    39 1
    
    94 88
    
    89 96
    
    79 46
    
    33 75
    
    31 42
    
    33 95
    
    6 83
    
    90 66
    
    37 54
    
    35 64
    
    17 66
    
    48 37
    
    30 8
    
    95 51
    
    3 51
    
    90 33
    
    29 48
    
    94 78
    
    53 7
    
    1 26
    
    73 35
    
    18 33
    
    99 78
    
    83 59
    
    23 87
    
    4 17
    
    53 91
    
    98 3
    
    54 82
    
    85 92
    
    77 8
    
    56 74
    
    4 5
    
    63 1
    
    26 8
    
    42 15
    
    48 98
    
    27 11
    
    70 98
    
    36 9
    
    78 92
    
    34 40
    
    42 82
    
    64 83
    
    75 47
    
    2 51 55
    
    1 7 62
    
    2 21 62
    
    1 36 39
    
    1 35 89
    
    1 84 15
    
    2 19 24
    
    1 58 53
    
    2 52 34
    
    1 98 49
    
    1 4 100
    
    1 17 25
    
    1 30 56
    
    1 69 43
    
    2 57 23
    
    2 23 13
    
    1 98 25
    
    2 50 27
    
    1 84 63
    
    2 84 81
    
    2 84 77
    
    1 60 23
    
    2 15 27
    
    1 9 51
    
    1 31 11
    
    1 96 56
    
    2 20 85
    
    1 46 32
    
    1 60 88
    
    2 92 48
    
    1 68 5
    
    2 90 17
    
    1 16 46
    
    2 67 5
    
    2 29 83
    
    1 84 70
    
    2 68 27
    
    1 99 33
    
    2 39 89
    
    2 38 28
    
    1 42 3
    
    1 10 60
    
    2 56 29
    
    2 12 60
    
    2 46 51
    
    2 15 73
    
    1 93 42
    
    1 78 82
    
    1 66 20
    
    1 46 17
    
    2 48 5
    
    1 59 61
    
    1 87 59
    
    2 98 72
    
    1 49 3
    
    2 21 10
    
    1 15 4
    
    1 48 14
    
    2 67 75
    
    2 83 77
    
    1 88 65
    
    2 100 93
    
    2 58 83
    
    1 29 80
    
    2 31 88
    
    2 92 94
    
    1 96 66
    
    1 61 82
    
    2 87 24
    
    1 64 83
    
    1 28 87
    
    2 72 90
    
    2 7 3
    
    1 86 3
    
    2 26 53
    
    2 71 2
    
    2 88 24
    
    1 69 60
    
    1 92 44
    
    2 74 94
    
    1 12 78
    
    2 1 2
    
    1 4 73
    
    1 58 5
    
    1 62 14
    
    2 64 58
    
    2 39 45
    
    1 99 27
    
    1 42 21
    
    1 87 2
    
    2 16 98
    
    2 17 21
    
    2 41 20
    
    1 46 72
    
    1 11 62
    
    2 68 29
    
    1 64 66
    
    2 90 42
    
    2 63 35
    
    1 64 71
    Sample Input

    Sample Output

    3
    
    8
    
    6
    
    7
    
    7
    
    6
    
    6
    
    12
    
    11
    
    4
    
    5
    
    6
    
    8
    
    1
    
    7
    
    6
    
    4
    
    9
    
    2
    
    2
    
    8
    
    9
    
    6
    
    4
    
    7
    
    5
    
    8
    
    7
    
    5
    
    5
    
    5
    
    7
    
    7
    
    5
    
    6
    
    6
    
    8
    
    6
    
    0
    
    2
    
    7
    
    12
    
    4
    
    2
    
    8
    
    3
    
    10
    Sample Output

    HINT

    Source

    Vani原创 欢迎移步 OJ2648

    Solution

    双倍经验题,KD Tree模板题

    KD Tree是一种切割多维空间的数据结构,主要用于多维空间信息的搜索(范围搜索和最近邻搜索)

    大体上每层按照不同的维度进行左右建树,分开平面上的点,本质还是一颗平衡二叉树

    效率大概是$O(log^{2}N)$的,比较暴力的做法

    Code

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    using namespace std;
    int read()
    {
        int x=0,f=1; char ch=getchar();
        while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
        while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    #define maxn 500010
    int n,m,D;
    struct PointNode
    {
        int d[2],mn[2],mx[2],l,r;
        PointNode(int x=0,int y=0) {l=r=0;d[0]=x;d[1]=y;}
        bool operator < (const PointNode & A) const {return d[D]<A.d[D];}
    }p[maxn];
    int dis(PointNode a,PointNode b) {return abs(a.d[0]-b.d[0])+abs(a.d[1]-b.d[1]);}
    struct K_DTreeNode
    {
        int rt,ans;
        PointNode Point,tree[maxn<<1];
        void Update(int now)
            {
                for (int i=0; i<=1; i++)
                    {
                        if (tree[now].l) 
                            tree[now].mn[i]=min(tree[now].mn[i],tree[tree[now].l].mn[i]),tree[now].mx[i]=max(tree[now].mx[i],tree[tree[now].l].mx[i]);
                        if (tree[now].r) 
                            tree[now].mn[i]=min(tree[now].mn[i],tree[tree[now].r].mn[i]),tree[now].mx[i]=max(tree[now].mx[i],tree[tree[now].r].mx[i]);
                    }
            }
        int BuildTree(int l,int r,int dd)
            {
                D=dd; int mid=(l+r)>>1;
                nth_element(p+l,p+mid,p+r+1);
                tree[mid]=p[mid];
                for (int i=0; i<=1; i++) tree[mid].mn[i]=tree[mid].mx[i]=tree[mid].d[i];
                if (l<mid) tree[mid].l=BuildTree(l,mid-1,dd^1);
                if (r>mid) tree[mid].r=BuildTree(mid+1,r,dd^1);
                Update(mid);
                return mid;
            }
        void Insert(int now,int dd)
            {        
                if (Point.d[dd]>=tree[now].d[dd])
                    if (tree[now].r) Insert(tree[now].r,dd^1);
                    else
                        {
                            tree[now].r=++n; tree[n]=Point;
                            for (int i=0; i<=1; i++) tree[n].mn[i]=tree[n].mx[i]=tree[n].d[i];                
                        }
                else
                    if (tree[now].l) Insert(tree[now].l,dd^1);
                    else
                        {
                            tree[now].l=++n; tree[n]=Point;
                            for (int i=0; i<=1; i++) tree[n].mn[i]=tree[n].mx[i]=tree[n].d[i];                
                        }
                Update(now);            
            }
        int dist(int p1,PointNode p)
            {
                   int re=0;
                   for (int i=0; i<=1; i++) re+=max(0,tree[p1].mn[i]-p.d[i]);
                   for (int i=0; i<=1; i++) re+=max(0,p.d[i]-tree[p1].mx[i]);
                   return re;
            }
        void Query(int now,int dd)
            {
                   int dl,dr,d0;
                   d0=dis(tree[now],Point);
                   if (d0<ans) ans=d0;
                   if (tree[now].l) dl=dist(tree[now].l,Point); else dl=0x7f7f7f7f;
                   if (tree[now].r) dr=dist(tree[now].r,Point); else dr=0x7f7f7f7f;
                   if (dl<dr)
                    {
                           if (dl<ans) Query(tree[now].l,dd^1);
                           if (dr<ans) Query(tree[now].r,dd^1);
                       }
                else
                    {
                           if (dr<ans) Query(tree[now].r,dd^1);
                           if (dl<ans) Query(tree[now].l,dd^1);
                       }        
        }
        void insert(PointNode _p){Point=_p; Insert(rt,0);}
        void init(){rt=BuildTree(1,n,0);}
        int query(PointNode _p){Point=_p;ans=0x7fffffff; Query(rt,0); return ans;}
    }KDT;
    int main()
    {
    //    freopen("angel.in","r",stdin); freopen("angel.out","w",stdout);
        n=read(),m=read();
        for (int i=1; i<=n; i++) p[i].d[0]=read(),p[i].d[1]=read(); 
        KDT.init();
        for (int i=1; i<=m; i++) 
            {
                int opt=read(),x=read(),y=read();
                if (opt==1) KDT.insert(PointNode(x,y));
                if (opt==2) printf("%d
    ",KDT.query(PointNode(x,y)));
            }
        return 0;
    }

    模板是参考的zky学长的,zky学长好神%%%

  • 相关阅读:
    apply()和call()的区别
    强制类型转换
    浮动理解
    清除浮动的方式
    五大主流浏览器及四大内核
    CSS引入方式
    js构建类的方法
    web前端与后端的理解区分
    Java的API及Object
    面向对象之this关键字
  • 原文地址:https://www.cnblogs.com/DaD3zZ-Beyonder/p/5518614.html
Copyright © 2011-2022 走看看