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总的点数目
每次处理后到达重链外的点(若是重链内的点,判断结束)
- #include <cstdio>
- #include <cstdlib>
- #include <cmath>
- #include <cstring>
- #include <string>
- #include <algorithm>
- #include <iostream>
- using namespace std;
- #define ll long long
- const double eps=1e-;
- const ll inf=1e9;
- const ll mod=1e9+;
- const int maxn=2e5+;
- struct node
- {
- int d;
- node *to;
- }*e[maxn];
- char str[];
- int siz[maxn],fa[maxn],link[maxn],cnt_link;
- void dfs(int d)
- {
- node *p=e[d];
- siz[d]=;
- while (p)
- {
- if (fa[d]!=p->d)
- {
- fa[p->d]=d;
- dfs(p->d);
- siz[d]+=siz[p->d];
- }
- p=p->to;
- }
- }
- void findleaf(int d)
- {
- node *p;
- int num;
- cnt_link=;
- link[]=d;
- while ()
- {
- p=e[d];
- num=;
- while (p)
- {
- if (fa[d]!=p->d)
- {
- if (siz[p->d]>siz[num])
- num=p->d;
- }
- p=p->to;
- }
- if (!num)
- break;
- link[++cnt_link]=num;
- d=num;
- }
- }
- int main()
- {
- node *p;
- int n,x,y,i,root,dist,r,pos;
- scanf("%d",&n);
- for (i=;i<n;i++)
- {
- scanf("%d%d",&x,&y);
- p=new node();
- p->d=y;
- p->to=e[x];
- e[x]=p;
- p=new node();
- p->d=x;
- p->to=e[y];
- e[y]=p;
- }
- gets(str);
- printf("d %d\n",);
- fflush(stdout);
- scanf("%d",&dist);
- if (dist==)
- {
- printf("! %d\n",);
- fflush(stdout);
- return ;
- }
- root=;
- while ()
- {
- dfs(root);
- findleaf(root);
- printf("d %d\n",link[cnt_link]);
- fflush(stdout);
- scanf("%d",&r);
- pos=(dist+cnt_link-r)/;
- root=link[pos];
- dist=dist-pos;
- if (dist==)
- {
- printf("! %d\n",root);
- fflush(stdout);
- return ;
- }
- printf("s %d\n",root);
- fflush(stdout);
- scanf("%d",&root);
- dist--;
- if (dist==)
- {
- printf("! %d\n",root);
- fflush(stdout);
- return ;
- }
- }
- return ;
- }
- /*
- 6
- 1 2
- 2 3
- 3 4
- 4 5
- 5 6
- 7
- 1 2
- 1 3
- 2 4
- 2 5
- 3 6
- 3 7
- 7
- 1 2
- 1 3
- 2 4
- 2 5
- 3 6
- 3 7
- d 1
- 2
- d 7
- 4
- s 1
- 2
- d 7
- */
树重心(点分治)
作为树重心的点,若干个子树
max(size of subtree) 最小
子树的大小均小于 < 1/2总的点数目
每次处理后到达新当前树重心的子树(若是树重心,判断结束)
- #include <cstdio>
- #include <cstdlib>
- #include <cmath>
- #include <cstring>
- #include <string>
- #include <algorithm>
- #include <iostream>
- using namespace std;
- #define ll long long
- const double eps=1e-;
- const ll inf=1e9;
- const ll mod=1e9+;
- const int maxn=2e5+;
- /*
- fa
- 用于cdq分治比较好
- */
- struct node
- {
- int d;
- node *to;
- }*e[maxn];
- char str[];
- int siz[maxn],fa[maxn],dep[maxn],minsiz,root,pre_root,nn;
- bool hav[maxn];
- void dfs(int d)
- {
- int maxs=;
- node *p=e[d];
- siz[d]=;
- while (p)
- {
- if (fa[d]!=p->d && !hav[p->d])
- {
- fa[p->d]=d;
- dep[p->d]=dep[d]+;
- dfs(p->d);
- siz[d]+=siz[p->d];
- maxs=max(maxs,siz[p->d]);
- }
- p=p->to;
- }
- maxs=max(maxs,nn-siz[d]);
- if (maxs<minsiz)
- minsiz=maxs,root=d;
- }
- int main()
- {
- node *p;
- int n,x,y,i,r,dist;
- scanf("%d",&n);
- for (i=;i<n;i++)
- {
- scanf("%d%d",&x,&y);
- p=new node();
- p->d=y;
- p->to=e[x];
- e[x]=p;
- p=new node();
- p->d=x;
- p->to=e[y];
- e[y]=p;
- }
- gets(str);
- printf("d %d\n",);
- fflush(stdout);
- scanf("%d",&dist);
- if (dist==)
- {
- printf("! %d\n",);
- fflush(stdout);
- return ;
- }
- nn=n;
- root=;
- while ()
- {
- pre_root=root;
- dep[pre_root]=;
- minsiz=inf;
- dfs(root);
- if (root==pre_root)
- {
- printf("s %d\n",root);
- fflush(stdout);
- hav[root]=;
- scanf("%d",&root);
- dist--;
- if (dist==)
- {
- printf("! %d\n",root);
- fflush(stdout);
- return ;
- }
- nn=siz[root];
- }
- else
- {
- printf("d %d\n",root);
- fflush(stdout);
- scanf("%d",&r);
- if (r==)
- {
- printf("! %d\n",root);
- fflush(stdout);
- return ;
- }
- hav[root]=;
- if (r+dep[root]==dist)
- {
- printf("s %d\n",root);
- fflush(stdout);
- dist-=dep[root]+;
- scanf("%d",&root);
- if (dist==)
- {
- printf("! %d\n",root);
- fflush(stdout);
- return ;
- }
- nn=siz[root];
- }
- else
- {
- nn=siz[pre_root]-siz[root];
- root=pre_root;///so that no need to initialize array fa
- ///dist not change
- }
- }
- }
- return ;
- }
- /*
- 6
- 1 2
- 2 3
- 3 4
- 4 5
- 5 6
- 7
- 1 2
- 1 3
- 2 4
- 2 5
- 3 6
- 3 7
- 15
- 1 2
- 1 3
- 2 4
- 2 5
- 3 6
- 3 7
- 4 8
- 4 9
- 5 10
- 5 11
- 6 12
- 6 13
- 7 14
- 7 15
- 7
- 1 2
- 2 3
- 3 4
- 4 5
- 3 6
- 3 7
- 12
- 1 2
- 2 3
- 2 4
- 4 5
- 4 6
- 1 7
- 7 8
- 8 9
- 9 10
- 9 11
- 11 12
- 7
- 1 2
- 1 3
- 1 4
- 1 5
- 1 6
- 6 7
- 9
- 1 2
- 2 3
- 3 4
- 4 5
- 1 6
- 1 7
- 1 8
- 1 9
- 8
- 1 2
- 2 3
- 3 4
- 2 5
- 5 6
- 5 7
- 5 8
- */
为了省去vis初始化
way1:
use father vex
way2:
vis[d]=1;
...
vis[d]=0;
- #include <cstdio>
- #include <cstdlib>
- #include <cmath>
- #include <cstring>
- #include <string>
- #include <algorithm>
- #include <iostream>
- using namespace std;
- #define ll long long
- const double eps=1e-;
- const ll inf=1e9;
- const ll mod=1e9+;
- const int maxn=2e5+;
- struct node
- {
- int d;
- node *to;
- }*e[maxn];
- char str[];
- int siz[maxn],fa[maxn],link[maxn],cnt_link;
- void dfs(int d)
- {
- node *p=e[d];
- siz[d]=;
- while (p)
- {
- if (fa[d]!=p->d)
- {
- fa[p->d]=d;
- dfs(p->d);
- siz[d]+=siz[p->d];
- }
- p=p->to;
- }
- }
- void findleaf(int d)
- {
- node *p;
- int num;
- cnt_link=;
- link[]=d;
- while ()
- {
- p=e[d];
- num=;
- while (p)
- {
- if (fa[d]!=p->d)
- {
- if (siz[p->d]>siz[num])
- num=p->d;
- }
- p=p->to;
- }
- if (!num)
- break;
- link[++cnt_link]=num;
- d=num;
- }
- }
- int main()
- {
- node *p;
- int n,x,y,i,root,dist,r,pos;
- scanf("%d",&n);
- for (i=;i<n;i++)
- {
- scanf("%d%d",&x,&y);
- p=new node();
- p->d=y;
- p->to=e[x];
- e[x]=p;
- p=new node();
- p->d=x;
- p->to=e[y];
- e[y]=p;
- }
- gets(str);
- printf("d %d\n",);
- fflush(stdout);
- scanf("%d",&dist);
- if (dist==)
- {
- printf("! %d\n",);
- fflush(stdout);
- return ;
- }
- root=;
- while ()
- {
- fa[root]=;
- dfs(root);
- findleaf(root);
- printf("d %d\n",link[cnt_link]);
- fflush(stdout);
- scanf("%d",&r);
- if (r==)
- {
- printf("! %d\n",link[cnt_link]);
- fflush(stdout);
- return ;
- }
- pos=(dist+cnt_link-r)/;
- root=link[pos];
- dist=dist-pos;
- if (dist==)
- {
- printf("! %d\n",root);
- fflush(stdout);
- return ;
- }
- printf("s %d\n",root);
- fflush(stdout);
- scanf("%d",&root);
- dist--;
- if (dist==)
- {
- printf("! %d\n",root);
- fflush(stdout);
- return ;
- }
- }
- return ;
- }
- /*
- 6
- 1 2
- 2 3
- 3 4
- 4 5
- 5 6
- */
- #include <cstdio>
- #include <cstdlib>
- #include <cmath>
- #include <cstring>
- #include <string>
- #include <algorithm>
- #include <iostream>
- using namespace std;
- #define ll long long
- const double eps=1e-;
- const ll inf=1e9;
- const ll mod=1e9+;
- const int maxn=2e5+;
- struct node
- {
- int d;
- node *to;
- }*e[maxn];
- char str[];
- int siz[maxn],fa[maxn],link[maxn],cnt_link;
- bool vis[maxn];
- void dfs(int d)
- {
- node *p=e[d];
- vis[d]=;
- siz[d]=;
- while (p)
- {
- if (!vis[p->d])
- {
- dfs(p->d);
- siz[d]+=siz[p->d];
- fa[p->d]=d;
- }
- p=p->to;
- }
- vis[d]=;
- }
- void findleaf(int d)
- {
- node *p;
- int num;
- cnt_link=;
- link[]=d;
- while ()
- {
- p=e[d];
- num=;
- while (p)
- {
- if (fa[d]!=p->d)
- {
- if (siz[p->d]>siz[num])
- num=p->d;
- }
- p=p->to;
- }
- if (!num)
- break;
- link[++cnt_link]=num;
- d=num;
- }
- }
- int main()
- {
- node *p;
- int n,x,y,i,root,dist,r,pos;
- scanf("%d",&n);
- for (i=;i<n;i++)
- {
- scanf("%d%d",&x,&y);
- p=new node();
- p->d=y;
- p->to=e[x];
- e[x]=p;
- p=new node();
- p->d=x;
- p->to=e[y];
- e[y]=p;
- }
- gets(str);
- printf("d %d\n",);
- fflush(stdout);
- scanf("%d",&dist);
- if (dist==)
- {
- printf("! %d\n",);
- fflush(stdout);
- return ;
- }
- root=;
- while ()
- {
- // memset(vis,0,sizeof(vis));
- fa[root]=;
- dfs(root);
- findleaf(root);
- printf("d %d\n",link[cnt_link]);
- fflush(stdout);
- scanf("%d",&r);
- if (r==)
- {
- printf("! %d\n",link[cnt_link]);
- fflush(stdout);
- return ;
- }
- pos=(dist+cnt_link-r)/;
- root=link[pos];
- dist=dist-pos;
- if (dist==)
- {
- printf("! %d\n",root);
- fflush(stdout);
- return ;
- }
- printf("s %d\n",root);
- fflush(stdout);
- scanf("%d",&root);
- dist--;
- if (dist==)
- {
- printf("! %d\n",root);
- fflush(stdout);
- return ;
- }
- }
- return ;
- }
- /*
- 6
- 1 2
- 2 3
- 3 4
- 4 5
- 5 6
- */
Codeforces Round #563 (Div. 2) F. Ehab and the Big Finale的更多相关文章
- 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 题意: 给出一颗点有权值的树 ...
- Codeforces Round #563 (Div. 2) E. Ehab and the Expected GCD Problem
https://codeforces.com/contest/1174/problem/E dp 好题 *(if 满足条件) 满足条件 *1 不满足条件 *0 ///这代码虽然写着方便,但是常数有点大 ...
- 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 ...
- 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 ...
- 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 ...
- 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 ...
- Codeforces Round #485 (Div. 2) F. AND Graph
Codeforces Round #485 (Div. 2) F. AND Graph 题目连接: http://codeforces.com/contest/987/problem/F Descri ...
- Codeforces Round #486 (Div. 3) F. Rain and Umbrellas
Codeforces Round #486 (Div. 3) F. Rain and Umbrellas 题目连接: http://codeforces.com/group/T0ITBvoeEx/co ...
- Codeforces Round #501 (Div. 3) F. Bracket Substring
题目链接 Codeforces Round #501 (Div. 3) F. Bracket Substring 题解 官方题解 http://codeforces.com/blog/entry/60 ...
随机推荐
- USACO2007 The Bale Tower /// DFS oj21160
题目大意: 给出N个捆包,每个捆包有相应的长度和宽度,要求堆叠捆包,使下方的捆包长宽永远大于上方的捆包的长宽. Input Multiple test case. For each case: * L ...
- Android基础——框架模式MVC在安卓中的实践
本篇文章包含以下内容: MVC的介绍 MVC的实践 MVC的介绍 MVC (Model View Controller),是模型(model)视图(view)控制器(controller)的缩写,一种 ...
- windows 开启管理员权限
在使用cmd为windows系统的电脑添加一条路由的时候,发现提示我权限不足,经过我的查找,需要在 我的电脑 右键 管理 本地用户管理 打开用户一栏 找到管理员账户 右键打开属 ...
- IOS 表单含有input框和有position: fixed导致错位的问题
在input框聚焦失焦的时候,都调用以下js即可 setScrollTop() { let scrollTop = document.body.scrollTop + document.documen ...
- Laravel 项目运行 phpunit 测试结果只显示点号
在laravel 项目的根目录下,运行 phpunit 只显示 点号的情况 我尝试将 tests/Unit 和 tests/Feature 目录将 ExampleTest.php 文件删除,然后再运行 ...
- 14. static(静态) 关键字
1.修饰成员变量 1)定义:数据需要被共享给所有对象使用使用static修饰(全局变量) 2)注意: 1.用static中创建的成员变量在内存中只有一份 2.千万不要为了方便访问数据而使用static ...
- Android NDK 环境变量配置
NDK_ROOT = C:\__S_D_K__\AndroidNDK\android-ndk-r20 在path 中加入 %NDK_ROOT% 我的路径在C盘 //个别的程序可能需要 NDK_ROO ...
- 同构图+思维构造——牛客多校第六场E
考的其实是同构图的性质: 1.同构图的顶点数,边数相等 2.同构图通过点的映射后邻接矩阵相同 这篇博客讲的很好https://www.jianshu.com/p/c33b5d1b4cd9 本题还需要一 ...
- Python 爬取拉钩网工作岗位
如果拉钩网html页面做了调整,需要重新调整代码 代码如下 #/usr/bin/env python3 #coding:utf-8 import sys import json import requ ...
- BZOJ 4817: [Sdoi2017]树点涂色(lct+线段树)
传送门 解题思路 跟重组病毒这道题很像.只是有了一个询问\(2\)的操作,然后询问\(2\)的答案其实就是\(val[x]+val[y]-2*val[lca(x,y)]+1\)(画图理解).剩下的操作 ...