后续:

点分治标程

使用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的更多相关文章

  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. hdu6311 /// 欧拉路径 无向图最小路径覆盖 输出正反路径

    题目大意: 给定n m 为图的点数和边数 接下来m行 u v 为u到v有一条边 要求最少几笔能画完图的所有边 输出每笔画过的路径编号 正数编号正向 负数编号反向 题解:https://www.cnbl ...

  2. Unicode - 16 位统一超级字符集

    描述 (DESCRIPTION) 国际标准 ISO 10646 定义了 通用字符集 (Universal Character Set, UCS). UCS 包含所有别的字符集标准里的字符,并且保证了 ...

  3. 利用ffmpeg进行视频软解播放

    前段时间,公司的一个项目需要一个rtsp的播放库,原本打算直接用vlc播放的,但我觉得vlc太庞大了,很多功能没必要,还不如用ffmpeg+d3d简单的实现一个库,因此就有了今天讲的这个东西.一个解码 ...

  4. ubuntu配置阿里云源

    换成国内最快的阿里云源 第一步:备份原来的源文件 cd /etc/apt/ 然后会显示下面的源文件sources.list 输入命令 sudo cp sources.list sources.list ...

  5. CSIC_716_20191129【面向对象高级----反射、类的内置方法(魔法方法)、单例模式】

    反射 反射是通过'字符串'对 对象的属性进行操作,反射有四个内置的方法. hasattr 通过字符串 判断对象的属性或者方法是否存在 getattr 通过字符串  获取对象的属性或者方法        ...

  6. tp5 查询本年、本月、本周的方法

    tp5自带了一些查询的方法,今天说一下查询本年.本月以及本周的方法 whereTime()//此方法代替了between and 方法 实际用法如下: ->whereTime('时间字段','y ...

  7. Windows API DOC

    { /* https://docs.microsoft.com/zh-cn/?view=sql-server-ver15 */ }

  8. Go 静态类型声明

    Go 静态类型声明 package main import "fmt" func main() { var x float64 x = 20.0 fmt.Println(x) fm ...

  9. 杂项:ionic

    ylbtech-杂项:ionic ionic是一个用来开发混合手机应用的,开源的,免费的代码库.可以优化html.css和js的性能,构建高效的应用程序,而且还可以用于构建Sass和AngularJS ...

  10. LeetCode 1037. Valid Boomerang (有效的回旋镖)

    题目标签:Math 题目给了我们三个点,让我们判断这三个点是否在一条直线上. 利用斜率 k = (y1 - y0) / (x1 - x0) 来判断,如果 三个点 abc, ab 的斜率 = bc 的斜 ...