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\n",1);
 89     fflush(stdout);
 90     scanf("%d",&dist);
 91     if (dist==0)
 92     {
 93         printf("! %d\n",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\n",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\n",root);
114             fflush(stdout);
115             return 0;
116         }
117 
118         printf("s %d\n",root);
119         fflush(stdout);
120         scanf("%d",&root);
121         dist--;
122         if (dist==0)
123         {
124             printf("! %d\n",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\n",1);
 74     fflush(stdout);
 75     scanf("%d",&dist);
 76     if (dist==0)
 77     {
 78         printf("! %d\n",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\n",root);
 95             fflush(stdout);
 96             hav[root]=1;
 97             scanf("%d",&root);
 98             dist--;
 99             if (dist==0)
100             {
101                 printf("! %d\n",root);
102                 fflush(stdout);
103                 return 0;
104             }
105             nn=siz[root];
106         }
107         else
108         {
109             printf("d %d\n",root);
110             fflush(stdout);
111             scanf("%d",&r);
112 
113             if (r==0)
114             {
115                 printf("! %d\n",root);
116                 fflush(stdout);
117                 return 0;
118             }
119 
120             hav[root]=1;
121             if (r+dep[root]==dist)
122             {
123                 printf("s %d\n",root);
124                 fflush(stdout);
125                 dist-=dep[root]+1;
126                 scanf("%d",&root);
127 
128                 if (dist==0)
129                 {
130                     printf("! %d\n",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\n",1);
 89         fflush(stdout);
 90         scanf("%d",&dist);
 91         if (dist==0)
 92         {
 93             printf("! %d\n",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\n",link[cnt_link]);
106             fflush(stdout);
107             scanf("%d",&r);
108             if (r==0)
109             {
110                 printf("! %d\n",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\n",root);
121                 fflush(stdout);
122                 return 0;
123             }
124      
125             printf("s %d\n",root);
126             fflush(stdout);
127             scanf("%d",&root);
128             dist--;
129             if (dist==0)
130             {
131                 printf("! %d\n",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\n",1);
 92         fflush(stdout);
 93         scanf("%d",&dist);
 94         if (dist==0)
 95         {
 96             printf("! %d\n",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\n",link[cnt_link]);
110             fflush(stdout);
111             scanf("%d",&r);
112             if (r==0)
113             {
114                 printf("! %d\n",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\n",root);
125                 fflush(stdout);
126                 return 0;
127             }
128      
129             printf("s %d\n",root);
130             fflush(stdout);
131             scanf("%d",&root);
132             dist--;
133             if (dist==0)
134             {
135                 printf("! %d\n",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     */

 

posted @ 2019-06-30 10:49  congmingyige  阅读(280)  评论(0编辑  收藏  举报