zoukankan      html  css  js  c++  java
  • Codeforces Round #563 (Div. 2) F. Ehab and the Big Finale

    后续:

    点分治标程

    使用father数组

    比使用vis数组优秀(不需要对vis初始化)

    https://codeforces.com/problemset/problem/1174/F

    https://codeforces.com/blog/entry/67388

    有助于理解树链剖分 和 点分治

    题解写得挺好

    重链

    重链中的点的子树的大小是最大的

    重链外的点作为根节点的 子树 大小 < 1/2总的点数目

    每次处理后到达重链外的点(若是重链内的点,判断结束)

      1 #include <cstdio>
      2 #include <cstdlib>
      3 #include <cmath>
      4 #include <cstring>
      5 #include <string>
      6 #include <algorithm>
      7 #include <iostream>
      8 using namespace std;
      9 #define ll long long
     10 
     11 
     12 const double eps=1e-8;
     13 const ll inf=1e9;
     14 const ll mod=1e9+7;
     15 const int maxn=2e5+10;
     16 
     17 struct node
     18 {
     19     int d;
     20     node *to;
     21 }*e[maxn];
     22 
     23 char str[20];
     24 int siz[maxn],fa[maxn],link[maxn],cnt_link;
     25 
     26 void dfs(int d)
     27 {
     28     node *p=e[d];
     29     siz[d]=1;
     30     while (p)
     31     {
     32         if (fa[d]!=p->d)
     33         {
     34             fa[p->d]=d;
     35             dfs(p->d);
     36             siz[d]+=siz[p->d];
     37         }
     38         p=p->to;
     39     }
     40 }
     41 
     42 void findleaf(int d)
     43 {
     44     node *p;
     45     int num;
     46     cnt_link=0;
     47     link[0]=d;
     48     while (1)
     49     {
     50         p=e[d];
     51         num=0;
     52         while (p)
     53         {
     54             if (fa[d]!=p->d)
     55             {
     56                 if (siz[p->d]>siz[num])
     57                     num=p->d;
     58             }
     59             p=p->to;
     60         }
     61         if (!num)
     62             break;
     63         link[++cnt_link]=num;
     64         d=num;
     65     }
     66 }
     67 
     68 int main()
     69 {
     70     node *p;
     71     int n,x,y,i,root,dist,r,pos;
     72     scanf("%d",&n);
     73     for (i=1;i<n;i++)
     74     {
     75         scanf("%d%d",&x,&y);
     76         p=new node();
     77         p->d=y;
     78         p->to=e[x];
     79         e[x]=p;
     80 
     81         p=new node();
     82         p->d=x;
     83         p->to=e[y];
     84         e[y]=p;
     85     }
     86     gets(str);
     87 
     88     printf("d %d
    ",1);
     89     fflush(stdout);
     90     scanf("%d",&dist);
     91     if (dist==0)
     92     {
     93         printf("! %d
    ",1);
     94         fflush(stdout);
     95         return 0;
     96     }
     97 
     98     root=1;
     99     while (1)
    100     {
    101         dfs(root);
    102         findleaf(root);
    103 
    104         printf("d %d
    ",link[cnt_link]);
    105         fflush(stdout);
    106         scanf("%d",&r);
    107 
    108         pos=(dist+cnt_link-r)/2;
    109         root=link[pos];
    110         dist=dist-pos;
    111         if (dist==0)
    112         {
    113             printf("! %d
    ",root);
    114             fflush(stdout);
    115             return 0;
    116         }
    117 
    118         printf("s %d
    ",root);
    119         fflush(stdout);
    120         scanf("%d",&root);
    121         dist--;
    122         if (dist==0)
    123         {
    124             printf("! %d
    ",root);
    125             fflush(stdout);
    126             return 0;
    127         }
    128     }
    129     return 0;
    130 }
    131 /*
    132 6
    133 1 2
    134 2 3
    135 3 4
    136 4 5
    137 5 6
    138 
    139 7
    140 1 2
    141 1 3
    142 2 4
    143 2 5
    144 3 6
    145 3 7
    146 
    147 
    148 
    149 7
    150 1 2
    151 1 3
    152 2 4
    153 2 5
    154 3 6
    155 3 7
    156 d 1
    157 2
    158 d 7
    159 4
    160 s 1
    161 2
    162 d 7
    163 */

    树重心(点分治)

    作为树重心的点,若干个子树

    max(size of subtree) 最小

    子树的大小均小于 < 1/2总的点数目

    每次处理后到达新当前树重心的子树(若是树重心,判断结束)

      1 #include <cstdio>
      2 #include <cstdlib>
      3 #include <cmath>
      4 #include <cstring>
      5 #include <string>
      6 #include <algorithm>
      7 #include <iostream>
      8 using namespace std;
      9 #define ll long long
     10 
     11 const double eps=1e-8;
     12 const ll inf=1e9;
     13 const ll mod=1e9+7;
     14 const int maxn=2e5+10;
     15 
     16 /*
     17 fa
     18 用于cdq分治比较好
     19 */
     20 
     21 struct node
     22 {
     23     int d;
     24     node *to;
     25 }*e[maxn];
     26 
     27 char str[20];
     28 int siz[maxn],fa[maxn],dep[maxn],minsiz,root,pre_root,nn;
     29 bool hav[maxn];
     30 
     31 void dfs(int d)
     32 {
     33     int maxs=0;
     34     node *p=e[d];
     35     siz[d]=1;
     36     while (p)
     37     {
     38         if (fa[d]!=p->d && !hav[p->d])
     39         {
     40             fa[p->d]=d;
     41             dep[p->d]=dep[d]+1;
     42             dfs(p->d);
     43             siz[d]+=siz[p->d];
     44             maxs=max(maxs,siz[p->d]);
     45         }
     46         p=p->to;
     47     }
     48     maxs=max(maxs,nn-siz[d]);
     49     if (maxs<minsiz)
     50         minsiz=maxs,root=d;
     51 }
     52 
     53 int main()
     54 {
     55     node *p;
     56     int n,x,y,i,r,dist;
     57     scanf("%d",&n);
     58     for (i=1;i<n;i++)
     59     {
     60         scanf("%d%d",&x,&y);
     61         p=new node();
     62         p->d=y;
     63         p->to=e[x];
     64         e[x]=p;
     65 
     66         p=new node();
     67         p->d=x;
     68         p->to=e[y];
     69         e[y]=p;
     70     }
     71     gets(str);
     72 
     73     printf("d %d
    ",1);
     74     fflush(stdout);
     75     scanf("%d",&dist);
     76     if (dist==0)
     77     {
     78         printf("! %d
    ",1);
     79         fflush(stdout);
     80         return 0;
     81     }
     82 
     83     nn=n;
     84     root=1;
     85     while (1)
     86     {
     87         pre_root=root;
     88         dep[pre_root]=0;
     89         minsiz=inf;
     90         dfs(root);
     91 
     92         if (root==pre_root)
     93         {
     94             printf("s %d
    ",root);
     95             fflush(stdout);
     96             hav[root]=1;
     97             scanf("%d",&root);
     98             dist--;
     99             if (dist==0)
    100             {
    101                 printf("! %d
    ",root);
    102                 fflush(stdout);
    103                 return 0;
    104             }
    105             nn=siz[root];
    106         }
    107         else
    108         {
    109             printf("d %d
    ",root);
    110             fflush(stdout);
    111             scanf("%d",&r);
    112 
    113             if (r==0)
    114             {
    115                 printf("! %d
    ",root);
    116                 fflush(stdout);
    117                 return 0;
    118             }
    119 
    120             hav[root]=1;
    121             if (r+dep[root]==dist)
    122             {
    123                 printf("s %d
    ",root);
    124                 fflush(stdout);
    125                 dist-=dep[root]+1;
    126                 scanf("%d",&root);
    127 
    128                 if (dist==0)
    129                 {
    130                     printf("! %d
    ",root);
    131                     fflush(stdout);
    132                     return 0;
    133                 }
    134                 nn=siz[root];
    135             }
    136             else
    137             {
    138                 nn=siz[pre_root]-siz[root];
    139                 root=pre_root;///so that no need to initialize array fa
    140                 ///dist not change
    141             }
    142         }
    143     }
    144     return 0;
    145 }
    146 /*
    147 6
    148 1 2
    149 2 3
    150 3 4
    151 4 5
    152 5 6
    153 
    154 7
    155 1 2
    156 1 3
    157 2 4
    158 2 5
    159 3 6
    160 3 7
    161 
    162 15
    163 1 2
    164 1 3
    165 2 4
    166 2 5
    167 3 6
    168 3 7
    169 4 8
    170 4 9
    171 5 10
    172 5 11
    173 6 12
    174 6 13
    175 7 14
    176 7 15
    177 
    178 7
    179 1 2
    180 2 3
    181 3 4
    182 4 5
    183 3 6
    184 3 7
    185 
    186 12
    187 1 2
    188 2 3
    189 2 4
    190 4 5
    191 4 6
    192 1 7
    193 7 8
    194 8 9
    195 9 10
    196 9 11
    197 11 12
    198 
    199 7
    200 1 2
    201 1 3
    202 1 4
    203 1 5
    204 1 6
    205 6 7
    206 
    207 9
    208 1 2
    209 2 3
    210 3 4
    211 4 5
    212 1 6
    213 1 7
    214 1 8
    215 1 9
    216 
    217 8
    218 1 2
    219 2 3
    220 3 4
    221 2 5
    222 5 6
    223 5 7
    224 5 8
    225 */

    为了省去vis初始化

    way1:

    use father vex

    way2:

    vis[d]=1;

    ...

    vis[d]=0;

      1     #include <cstdio>
      2     #include <cstdlib>
      3     #include <cmath>
      4     #include <cstring>
      5     #include <string>
      6     #include <algorithm>
      7     #include <iostream>
      8     using namespace std;
      9     #define ll long long
     10      
     11      
     12     const double eps=1e-8;
     13     const ll inf=1e9;
     14     const ll mod=1e9+7;
     15     const int maxn=2e5+10;
     16      
     17     struct node
     18     {
     19         int d;
     20         node *to;
     21     }*e[maxn];
     22      
     23     char str[20];
     24     int siz[maxn],fa[maxn],link[maxn],cnt_link;
     25      
     26     void dfs(int d)
     27     {
     28         node *p=e[d];
     29         siz[d]=1;
     30         while (p)
     31         {
     32             if (fa[d]!=p->d)
     33             {
     34                 fa[p->d]=d;
     35                 dfs(p->d);
     36                 siz[d]+=siz[p->d];
     37             }
     38             p=p->to;
     39         }
     40     }
     41      
     42     void findleaf(int d)
     43     {
     44         node *p;
     45         int num;
     46         cnt_link=0;
     47         link[0]=d;
     48         while (1)
     49         {
     50             p=e[d];
     51             num=0;
     52             while (p)
     53             {
     54                 if (fa[d]!=p->d)
     55                 {
     56                     if (siz[p->d]>siz[num])
     57                         num=p->d;
     58                 }
     59                 p=p->to;
     60             }
     61             if (!num)
     62                 break;
     63             link[++cnt_link]=num;
     64             d=num;
     65         }
     66     }
     67      
     68     int main()
     69     {
     70         node *p;
     71         int n,x,y,i,root,dist,r,pos;
     72         scanf("%d",&n);
     73         for (i=1;i<n;i++)
     74         {
     75             scanf("%d%d",&x,&y);
     76             p=new node();
     77             p->d=y;
     78             p->to=e[x];
     79             e[x]=p;
     80      
     81             p=new node();
     82             p->d=x;
     83             p->to=e[y];
     84             e[y]=p;
     85         }
     86         gets(str);
     87      
     88         printf("d %d
    ",1);
     89         fflush(stdout);
     90         scanf("%d",&dist);
     91         if (dist==0)
     92         {
     93             printf("! %d
    ",1);
     94             fflush(stdout);
     95             return 0;
     96         }
     97      
     98         root=1;
     99         while (1)
    100         {
    101             fa[root]=0;
    102             dfs(root);
    103             findleaf(root);
    104      
    105             printf("d %d
    ",link[cnt_link]);
    106             fflush(stdout);
    107             scanf("%d",&r);
    108             if (r==0)
    109             {
    110                 printf("! %d
    ",link[cnt_link]);
    111                 fflush(stdout);
    112                 return 0;
    113             }
    114      
    115             pos=(dist+cnt_link-r)/2;
    116             root=link[pos];
    117             dist=dist-pos;
    118             if (dist==0)
    119             {
    120                 printf("! %d
    ",root);
    121                 fflush(stdout);
    122                 return 0;
    123             }
    124      
    125             printf("s %d
    ",root);
    126             fflush(stdout);
    127             scanf("%d",&root);
    128             dist--;
    129             if (dist==0)
    130             {
    131                 printf("! %d
    ",root);
    132                 fflush(stdout);
    133                 return 0;
    134             }
    135         }
    136         return 0;
    137     }
    138     /*
    139     6
    140     1 2
    141     2 3
    142     3 4
    143     4 5
    144     5 6
    145      
    146     */
      1     #include <cstdio>
      2     #include <cstdlib>
      3     #include <cmath>
      4     #include <cstring>
      5     #include <string>
      6     #include <algorithm>
      7     #include <iostream>
      8     using namespace std;
      9     #define ll long long
     10      
     11      
     12     const double eps=1e-8;
     13     const ll inf=1e9;
     14     const ll mod=1e9+7;
     15     const int maxn=2e5+10;
     16      
     17     struct node
     18     {
     19         int d;
     20         node *to;
     21     }*e[maxn];
     22      
     23     char str[20];
     24     int siz[maxn],fa[maxn],link[maxn],cnt_link;
     25     bool vis[maxn];
     26      
     27     void dfs(int d)
     28     {
     29         node *p=e[d];
     30         vis[d]=1;
     31         siz[d]=1;
     32         while (p)
     33         {
     34             if (!vis[p->d])
     35             {
     36                 dfs(p->d);
     37                 siz[d]+=siz[p->d];
     38                 fa[p->d]=d;
     39             }
     40             p=p->to;
     41         }
     42         vis[d]=0;
     43     }
     44      
     45     void findleaf(int d)
     46     {
     47         node *p;
     48         int num;
     49         cnt_link=0;
     50         link[0]=d;
     51         while (1)
     52         {
     53             p=e[d];
     54             num=0;
     55             while (p)
     56             {
     57                 if (fa[d]!=p->d)
     58                 {
     59                     if (siz[p->d]>siz[num])
     60                         num=p->d;
     61                 }
     62                 p=p->to;
     63             }
     64             if (!num)
     65                 break;
     66             link[++cnt_link]=num;
     67             d=num;
     68         }
     69     }
     70      
     71     int main()
     72     {
     73         node *p;
     74         int n,x,y,i,root,dist,r,pos;
     75         scanf("%d",&n);
     76         for (i=1;i<n;i++)
     77         {
     78             scanf("%d%d",&x,&y);
     79             p=new node();
     80             p->d=y;
     81             p->to=e[x];
     82             e[x]=p;
     83      
     84             p=new node();
     85             p->d=x;
     86             p->to=e[y];
     87             e[y]=p;
     88         }
     89         gets(str);
     90      
     91         printf("d %d
    ",1);
     92         fflush(stdout);
     93         scanf("%d",&dist);
     94         if (dist==0)
     95         {
     96             printf("! %d
    ",1);
     97             fflush(stdout);
     98             return 0;
     99         }
    100      
    101         root=1;
    102         while (1)
    103         {
    104     //        memset(vis,0,sizeof(vis));
    105             fa[root]=0;
    106             dfs(root);
    107             findleaf(root);
    108      
    109             printf("d %d
    ",link[cnt_link]);
    110             fflush(stdout);
    111             scanf("%d",&r);
    112             if (r==0)
    113             {
    114                 printf("! %d
    ",link[cnt_link]);
    115                 fflush(stdout);
    116                 return 0;
    117             }
    118      
    119             pos=(dist+cnt_link-r)/2;
    120             root=link[pos];
    121             dist=dist-pos;
    122             if (dist==0)
    123             {
    124                 printf("! %d
    ",root);
    125                 fflush(stdout);
    126                 return 0;
    127             }
    128      
    129             printf("s %d
    ",root);
    130             fflush(stdout);
    131             scanf("%d",&root);
    132             dist--;
    133             if (dist==0)
    134             {
    135                 printf("! %d
    ",root);
    136                 fflush(stdout);
    137                 return 0;
    138             }
    139         }
    140         return 0;
    141     }
    142     /*
    143     6
    144     1 2
    145     2 3
    146     3 4
    147     4 5
    148     5 6
    149      
    150     */
  • 相关阅读:
    数组及其方法
    Web Worker
    nodejs输入输出
    head标签中的meta
    对象副本的拷贝
    bower指南(一)
    gulp指南(一)
    云服务器搭建
    http协议简单介绍(转)
    使用traits
  • 原文地址:https://www.cnblogs.com/cmyg/p/11108970.html
Copyright © 2011-2022 走看看