后续:

点分治标程

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

树重心(点分治)

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

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

Codeforces Round #563 (Div. 2) F. Ehab and the Big Finale的更多相关文章

  1. Codeforces Round #525 (Div. 2) F. Ehab and a weird weight formula

    F. Ehab and a weird weight formula 题目链接:https://codeforces.com/contest/1088/problem/F 题意: 给出一颗点有权值的树 ...

  2. Codeforces Round #563 (Div. 2) E. Ehab and the Expected GCD Problem

    https://codeforces.com/contest/1174/problem/E dp 好题 *(if 满足条件) 满足条件 *1 不满足条件 *0 ///这代码虽然写着方便,但是常数有点大 ...

  3. Codeforces Round #563 (Div. 2) C. Ehab and a Special Coloring Problem

    链接:https://codeforces.com/contest/1174/problem/C 题意: You're given an integer nn. For every integer i ...

  4. Codeforces Round #563 (Div. 2) B. Ehab Is an Odd Person

    链接:https://codeforces.com/contest/1174/problem/B 题意: You're given an array aa of length nn. You can ...

  5. Codeforces Round #563 (Div. 2) A. Ehab Fails to Be Thanos

    链接:https://codeforces.com/contest/1174/problem/A 题意: You're given an array aa of length 2n2n. Is it ...

  6. Codeforces Round #563 (Div. 2)/CF1174

    Codeforces Round #563 (Div. 2)/CF1174 CF1174A Ehab Fails to Be Thanos 其实就是要\(\sum\limits_{i=1}^n a_i ...

  7. Codeforces Round #485 (Div. 2) F. AND Graph

    Codeforces Round #485 (Div. 2) F. AND Graph 题目连接: http://codeforces.com/contest/987/problem/F Descri ...

  8. Codeforces Round #486 (Div. 3) F. Rain and Umbrellas

    Codeforces Round #486 (Div. 3) F. Rain and Umbrellas 题目连接: http://codeforces.com/group/T0ITBvoeEx/co ...

  9. Codeforces Round #501 (Div. 3) F. Bracket Substring

    题目链接 Codeforces Round #501 (Div. 3) F. Bracket Substring 题解 官方题解 http://codeforces.com/blog/entry/60 ...

随机推荐

  1. USACO2007 The Bale Tower /// DFS oj21160

    题目大意: 给出N个捆包,每个捆包有相应的长度和宽度,要求堆叠捆包,使下方的捆包长宽永远大于上方的捆包的长宽. Input Multiple test case. For each case: * L ...

  2. Android基础——框架模式MVC在安卓中的实践

    本篇文章包含以下内容: MVC的介绍 MVC的实践 MVC的介绍 MVC (Model View Controller),是模型(model)视图(view)控制器(controller)的缩写,一种 ...

  3. windows 开启管理员权限

    在使用cmd为windows系统的电脑添加一条路由的时候,发现提示我权限不足,经过我的查找,需要在 我的电脑   右键  管理   本地用户管理    打开用户一栏   找到管理员账户   右键打开属 ...

  4. IOS 表单含有input框和有position: fixed导致错位的问题

    在input框聚焦失焦的时候,都调用以下js即可 setScrollTop() { let scrollTop = document.body.scrollTop + document.documen ...

  5. Laravel 项目运行 phpunit 测试结果只显示点号

    在laravel 项目的根目录下,运行 phpunit 只显示 点号的情况 我尝试将 tests/Unit 和 tests/Feature 目录将 ExampleTest.php 文件删除,然后再运行 ...

  6. 14. static(静态) 关键字

    1.修饰成员变量 1)定义:数据需要被共享给所有对象使用使用static修饰(全局变量) 2)注意: 1.用static中创建的成员变量在内存中只有一份 2.千万不要为了方便访问数据而使用static ...

  7. Android NDK 环境变量配置

    NDK_ROOT = C:\__S_D_K__\AndroidNDK\android-ndk-r20 在path 中加入  %NDK_ROOT% 我的路径在C盘 //个别的程序可能需要 NDK_ROO ...

  8. 同构图+思维构造——牛客多校第六场E

    考的其实是同构图的性质: 1.同构图的顶点数,边数相等 2.同构图通过点的映射后邻接矩阵相同 这篇博客讲的很好https://www.jianshu.com/p/c33b5d1b4cd9 本题还需要一 ...

  9. Python 爬取拉钩网工作岗位

    如果拉钩网html页面做了调整,需要重新调整代码 代码如下 #/usr/bin/env python3 #coding:utf-8 import sys import json import requ ...

  10. BZOJ 4817: [Sdoi2017]树点涂色(lct+线段树)

    传送门 解题思路 跟重组病毒这道题很像.只是有了一个询问\(2\)的操作,然后询问\(2\)的答案其实就是\(val[x]+val[y]-2*val[lca(x,y)]+1\)(画图理解).剩下的操作 ...