zoukankan      html  css  js  c++  java
  • BZOJ2716: [Violet 3]天使玩偶(KD-Tree)

    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 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

    解题思路:

    样例好良心。

    写CDQ写腻了,这道题还是学一学KD-Tree吧。

    KD-Tree,可以认为是在K维空间上二分答案。

    将二分得到的顺序建树。

    这样的结构很难支持修改,所以暴力插入。

    应用替罪羊的想法,不优秀就暴力重建。

    时间复杂度玄学。(维护矩形曼哈顿距离)

    非常开心地AC

    代码:

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 typedef long long lnt;
      5 const int D=2;
      6 const int maxn=1000000;
      7 const double alpha=0.75;
      8 int here;
      9 struct KD_pnt{
     10     int v[D];
     11     bool friend operator < (KD_pnt x,KD_pnt y)
     12     {
     13         return x.v[here]<y.v[here];
     14     }
     15 }p[maxn];
     16 struct KD_trnt{
     17     KD_pnt val;
     18     KD_pnt mx;
     19     KD_pnt mn;
     20     int ls;
     21     int rs;
     22     int wgt;
     23 }kt[maxn],stdkt;
     24 int n,m;
     25 int ans;
     26 int top;
     27 int siz;
     28 int root;
     29 int bin[maxn];
     30 inline int read(void)
     31 {
     32     int anss=0,f=1;
     33     char ch=getchar();
     34     while(ch<'0'||ch>'9')
     35     {
     36         if(ch=='-')
     37             f=-f;
     38         ch=getchar();
     39     }
     40     while(ch>='0'&&ch<='9')
     41     {
     42         anss=anss*10+ch-'0';
     43         ch=getchar();
     44     }
     45     return anss*f;
     46 }
     47 int newp(void)
     48 {
     49     if(top)
     50         return bin[top--];
     51     return ++siz;
     52 }
     53 void Trash(int spc)
     54 {
     55     bin[++top]=spc;
     56     return ;
     57 }
     58 void apply(int &spc)
     59 {
     60     spc=newp();
     61     kt[spc]=stdkt;
     62     return ;
     63 }
     64 int Dist(KD_pnt a,KD_pnt b)
     65 {
     66     int ans=0;
     67     for(int i=0;i<D;i++)
     68         ans+=std::abs(a.v[i]-b.v[i]);
     69     return ans;
     70 }
     71 int assess(KD_pnt a,int spc)
     72 {
     73     int ans=0;
     74     for(int i=0;i<D;i++)
     75         ans+=std::max(0,a.v[i]-kt[spc].mx.v[i])+std::max(0,kt[spc].mn.v[i]-a.v[i]);
     76     return ans;
     77 }
     78 void pushup(int spc)
     79 {
     80     kt[spc].mx=kt[spc].mn=kt[spc].val;
     81     if(kt[spc].ls)
     82     {
     83         kt[spc].mx.v[0]=std::max(kt[spc].mx.v[0],kt[kt[spc].ls].mx.v[0]);
     84         kt[spc].mn.v[0]=std::min(kt[spc].mn.v[0],kt[kt[spc].ls].mn.v[0]);
     85         kt[spc].mx.v[1]=std::max(kt[spc].mx.v[1],kt[kt[spc].ls].mx.v[1]);
     86         kt[spc].mn.v[1]=std::min(kt[spc].mn.v[1],kt[kt[spc].ls].mn.v[1]);
     87     }
     88     if(kt[spc].rs)
     89     {
     90         kt[spc].mx.v[0]=std::max(kt[spc].mx.v[0],kt[kt[spc].rs].mx.v[0]);
     91         kt[spc].mn.v[0]=std::min(kt[spc].mn.v[0],kt[kt[spc].rs].mn.v[0]);
     92         kt[spc].mx.v[1]=std::max(kt[spc].mx.v[1],kt[kt[spc].rs].mx.v[1]);
     93         kt[spc].mn.v[1]=std::min(kt[spc].mn.v[1],kt[kt[spc].rs].mn.v[1]);
     94     }
     95     kt[spc].wgt=1+kt[kt[spc].ls].wgt+kt[kt[spc].rs].wgt;
     96     return ;
     97 }
     98 void build(int l,int r,int dim,int &spc)
     99 {
    100     if(l>r)
    101     {
    102         spc=0;
    103         return ;
    104     }
    105     apply(spc);
    106     here=dim;
    107     int mid=(l+r)>>1;
    108     std::nth_element(p+l,p+mid,p+r+1);
    109     kt[spc].val=p[mid];
    110     build(l,mid-1,dim^1,kt[spc].ls);
    111     build(mid+1,r,dim^1,kt[spc].rs);
    112     pushup(spc);
    113     return ;
    114 }
    115 void Destory(int spc,int sta)
    116 {
    117     if(kt[spc].ls)
    118         Destory(kt[spc].ls,sta);
    119     p[sta+kt[kt[spc].ls].wgt+1]=kt[spc].val;
    120     Trash(spc);
    121     if(kt[spc].rs)
    122         Destory(kt[spc].rs,sta+kt[kt[spc].ls].wgt+1);
    123     return ;
    124 }
    125 bool imbalance(int root)
    126 {
    127     return ((double)(std::max(kt[kt[root].ls].wgt,kt[kt[root].rs].wgt))>alpha*(double)(kt[root].wgt));
    128 }
    129 void rebuild(int &spc,int dim)
    130 {
    131     Destory(spc,0);
    132     build(1,kt[spc].wgt,dim,spc);
    133     return ;
    134 }
    135 void Insert(int &spc,KD_pnt x,int dim)
    136 {
    137     if(!spc)
    138     {
    139         apply(spc);
    140         kt[spc].val=x;
    141         pushup(spc);
    142         return ;
    143     }
    144     if(kt[spc].val.v[dim]<x.v[dim])
    145         Insert(kt[spc].rs,x,dim^1);
    146     else
    147         Insert(kt[spc].ls,x,dim^1);
    148     pushup(spc);
    149     if(imbalance(spc))
    150         rebuild(spc,dim);
    151     return ;
    152 }
    153 void Query(int spc,KD_pnt x)
    154 {
    155     if(!spc)
    156         return ;
    157     ans=std::min(ans,Dist(x,kt[spc].val));
    158     int disls,disrs;
    159     if(kt[spc].ls)
    160         disls=assess(x,kt[spc].ls);
    161     else
    162         disls=0x7f7f7f7f;
    163     if(kt[spc].rs)
    164         disrs=assess(x,kt[spc].rs);
    165     else
    166         disrs=0x7f7f7f7f;
    167     if(disls<disrs)
    168     {
    169         if(disls<ans)
    170             Query(kt[spc].ls,x);
    171         if(disrs<ans)
    172             Query(kt[spc].rs,x);
    173     }else{
    174         if(disrs<ans)
    175             Query(kt[spc].rs,x);
    176         if(disls<ans)
    177             Query(kt[spc].ls,x);
    178     }
    179     return ;
    180 }
    181 int main()
    182 {
    183     n=read();
    184     m=read();
    185     for(int i=1;i<=n;i++)
    186         p[i].v[0]=read(),p[i].v[1]=read();;
    187     build(1,n,0,root);
    188     while(m--)
    189     {
    190         int cmd;
    191         KD_pnt x;
    192         ans=0x7f7f7f7f;
    193         cmd=read();
    194         x.v[0]=read();
    195         x.v[1]=read();
    196         if(cmd==1)
    197             Insert(root,x,0);
    198         else{
    199             Query(root,x);
    200             printf("%d
    ",ans);
    201         }
    202     }
    203     return 0;
    204 }
  • 相关阅读:
    最优二叉树(简易版本)
    平衡二叉树(AVL树)基础操作
    二叉树的基础操作
    双向链表(C语言)
    循环链表(C语言)
    单向链表(C语言)
    jQuery
    js事件
    JDBC-扩展
    JDBC
  • 原文地址:https://www.cnblogs.com/blog-Dr-J/p/10115995.html
Copyright © 2011-2022 走看看