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 ...
随机推荐
- js中常用的正则表达式
我一般对正则的使用方式如下,该方法会返回一个boolean值,然后对这个返回值来进行判断 // 判断是否是整数 function isInt(num) { var reg = new RegExp(& ...
- rmq +二分暴力 hdu 5726
参考博客 题意:n 个数字的数列,有m个询问:求出 L 到 R 的 gcd(最大公约数 ),然后问这整个序列中有多少个区间的 gcd 和这个一样. 分析:L 到 R的gcd直接用RM ...
- 多flavor导致的源码依赖问题-- Cannot choose between the following configurations of project :sample:
一.背景: 当我们在源码依赖的时候经常会导致一些问题. 我们的主工程有如下配置,它依赖了一个sample的本地工程 flavorDimensions "demo" productF ...
- 转载:vs2010 问题 >LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
原文链接:http://www.cnblogs.com/newpanderking/articles/3372969.html >LINK : fatal error LNK1123: 转换到 ...
- apache + php 无法访问redis
1.在有扩展的情况下 2.测试连接 <?php $redis=new Redis(); $redis->connect('127.0.0.1',6379); echo "succ ...
- linux fcntl 对文件描述符控制
linux fcntl 对文件描述符控制 linux fcntl 对文件描述符控制 linux fcntl 对文件描述符控制
- boost 实现读写锁
#include <boost/thread/shared_mutex.hpp> #include <boost/thread/locks.hpp> using BoostMu ...
- 安装memcached报错:If it's already installed, specify its path using --with-libevent=/dir/
一.安装memcached,执行./configure --prefix=/usr/local/memcached时候报错: 问题:If it's already installed, specify ...
- MongoDB启动时遇到的问题
问题一:child process failed, exited with error number 100 原因分析:100是锁了 解决办法:#cd /usr/local/mongodb/data ...
- 线程池 一 ScheduledThreadPoolExecutor
java.util.concurrent public class ScheduledThreadPoolExecutor extends ThreadPoolExecutor implements ...