后续:

点分治标程

使用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. DevOps到底是什么鬼?DevOps介绍及工具推荐。

    什么是DevOps DevOps是Development和Operations的组合,是一组过程.方法与系统的统称,用于促进开发(应用程序/软件工程).技术运营和质量保障(QA)部门之间的沟通.协作与 ...

  2. 微信小程序之评分页面

    首先给大家看看做好的效果图: 一.接下来我们说一下评分这个功能: 实际上就是一个简单的js,首先我们遍历出小星星,此时默认给的五星好评,在给他们一个点击事件,当点击时,我们获取到当前点击的是第几颗:代 ...

  3. 多线程中join的解释(转)

    文章来源:https://www.zhihu.com/question/61446671 这个join可以理解为“加入”,其含义与英语里面讲“Come on,join us”中的join类似.假设线程 ...

  4. idea 在新建一个class的时候可以选择继承的父类

    1.把光标放在父类名称上按alt+enter可以生成子类 2. 选中implement abstract class

  5. 浏览器http跳转至https问题

    Chrome 浏览器 地址栏中输入 chrome://net-internals/#hsts 在 Delete domain security policies 中输入项目的域名,并 Delete 删 ...

  6. jquery获取select选中项 自定义属性的值

    <select id="serialNo" > <option value=''1' data-id="001">第一次</opt ...

  7. Zookeeper_CAP原则

    CAP原则 简单介绍CAP 想要进行分布式事务控制,CAP理论是我们必须要知道的: CAP原则:也叫CAP定理,指的是在一个分布式系统中,一致性.可用性.分区容错性三者不可兼得 一致性(Consist ...

  8. IDEA maven package失败

    选中要打包的模块,选择工具栏中的Build,选择Rebuild Module xxx,重新打包

  9. NX二次开发-UFUN获得当前图纸页有多少个视图UF_DRAW_ask_num_views

    #include <uf.h> #include <uf_draw.h> #include <uf_ui.h> UF_initialize(); //获得当前图纸页 ...

  10. string替换所有指定字符串(C++)【转载】

    转载自https://blog.csdn.net/a_222850215/article/details/79985504 C++的string提供了replace方法来实现字符串的替换,但是对于将字 ...