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 ...
随机推荐
- selenium3与Python3实战 web自动化测试框架✍✍✍
selenium3与Python3实战 web自动化测试框架 整个课程都看完了,这个课程的分享可以往下看,下面有链接,之前做java开发也做了一些年头,也分享下自己看这个视频的感受,单论单个知识点课 ...
- hdu6315 /// 线段树区间更新
题目大意: 给定n q 为序列的个数和操作的个数 给定n个数的序列b[]作为分母 初始全为0的序列a[]作为分子 两种操作 add l r 为a[]的l到r区间全部+1 query l r 为查询l到 ...
- C#实体类克隆
public static T Clone<T>(T source) { if (!typeof(T).IsSerializable) { throw new ArgumentExcept ...
- 解决Google Chrome浏览器字体模糊的问题
之前使用Google的Chrome浏览器一直觉得有时候,其显示的字体比较模糊,不管是Windows XP还是Windows 7都会出现要么显示的网页字体模糊,要么是Chrome浏览器本身显示的菜单模糊 ...
- PHP算法之有效的括号
给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效. 有效字符串需满足: 左括号必须用相同类型的右括号闭合.左括号必须以正确的顺序闭合.注意空字符串可被认为是 ...
- BCZM: Chapter 2
2.1 二进制数中 1 的个数 实现一个函数,输入一个无符号整数,输出该数二进制中的1的个数.例如把9表示成二进制是1001,有2位是1,因此如果输入9,该函数输出2 分析与解法 解法1:利用十进制和 ...
- Spring Boot 2.X 对 web 的开发支持(二)
Spring Boot 2.X 对 web 的支持开发 上章节的 Spring Boot 的入门案例,我们感受到 Spring Boot 简单的配置即可运行项目. 今天了解 Spring Boot 对 ...
- 【JZOJ6419】模拟旅行&【BZOJ5506】【luoguP5304】旅行者
description 某国有n座城市,这些城市之间通过m条单向道路相连,已知每条道路的长度. 不过,小X只对其中k座城市感兴趣. 为了更好地规划模拟旅行路线,提升模拟旅行的体验,小X想要知道他感兴趣 ...
- NX二次开发-UFUN设置环境变量UF_set_variable
NX9+VS2012 #include <uf.h> #include <stdio.h> UF_initialize(); //UFUN方式 //设置环境变量 int a = ...
- NX二次开发-UFUN参数选择对话框UF_UI_select_parameters
#include <uf.h> #include <uf_ui.h> #include <uf_modl.h> UF_initialize(); //参数选择对话框 ...