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 }
  • 相关阅读:
    LeetCode Count of Range Sum
    LeetCode 158. Read N Characters Given Read4 II
    LeetCode 157. Read N Characters Given Read4
    LeetCode 317. Shortest Distance from All Buildings
    LeetCode Smallest Rectangle Enclosing Black Pixels
    LeetCode 315. Count of Smaller Numbers After Self
    LeetCode 332. Reconstruct Itinerary
    LeetCode 310. Minimum Height Trees
    LeetCode 163. Missing Ranges
    LeetCode Verify Preorder Serialization of a Binary Tree
  • 原文地址:https://www.cnblogs.com/blog-Dr-J/p/10115995.html
Copyright © 2011-2022 走看看