后续:

点分治标程

使用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. [已解决]报错JSONDecodeError

    报错: 解决:

  2. 数据整理A

  3. 55-Ubuntu-软件安装

    1.通过apt安装/卸载软件 apt是advanced packaging tool, 是Linux下的一款安装包管理工具. 可以在终端中方便的安装/卸载/更新软件包. (1)安装软件 sudo ap ...

  4. 自动化监控系统(三) 搭建xadmin做网站后台

    Django有个自带的admin后台,不过界面不怎么好看,这里我用xadmin 我的python版本是3.5,可以使用支持py3的xadmin:https://github.com/sshwsfc/x ...

  5. ios网络学习------2 用非代理方法实现同步post请求

    #pragma mark - 这是私有方法,尽量不要再方法中直接使用属性,由于一般来说属性都是和界面关联的,我们能够通过參数的方式来使用属性 #pragma mark post登录方法 -(void) ...

  6. 008-Java的StringBuilder和StringBuffer

    StringBuffer 和 StringBuilder 与String的不同 String Java中十分重要的类;被声明为final class.除了hash这个属性, 其他属性也均声明为fina ...

  7. 关于apache 重定向设定

    本人在研究关于apache重定向的资料,在网上找了很多,但是就本人来说,方便理解的,找到了这么一个,记录了下来,原帖地址:http://www.exehack.net/8.html 关于apache配 ...

  8. GarsiaWachs算法

    解决石子问题: 题目描述如下: 有n堆石子排成一列,每堆石子有一个重量w[i], 每次合并可以合并相邻的两堆石子,一次合并的代价为两堆石子的重量和w[i]+w[i+1].问安排怎样的合并顺序,能够使得 ...

  9. 在sublime上安装markdown插件(win10)

    1.markdown插件安装 --ctrl+shift+p --在命令框中选中 package control:install package 选中它  按回车 --在命令框中输入 markdown, ...

  10. 1、Go语言的介绍

    一.概念 Go语言(Golang)是云计算时代的C语言,使用Go编译的程序可以媲美C/C++代码的速度,而且更加安全.支持并行进程. 二.Go语言的优势 1.部署简单.可以直接编译成机器码,不依赖其他 ...