Codeforecs Round #425 D Misha, Grisha and Underground (倍增LCA)
2 seconds
256 megabytes
standard input
standard output
Misha and Grisha are funny boys, so they like to use new underground. The underground has n stations connected with n - 1 routes so that each route connects two stations, and it is possible to reach every station from any other.
The boys decided to have fun and came up with a plan. Namely, in some day in the morning Misha will ride the underground from station sto station f by the shortest path, and will draw with aerosol an ugly text "Misha was here" on every station he will pass through (including sand f). After that on the same day at evening Grisha will ride from station t to station f by the shortest path and will count stations with Misha's text. After that at night the underground workers will wash the texts out, because the underground should be clean.
The boys have already chosen three stations a, b and c for each of several following days, one of them should be station s on that day, another should be station f, and the remaining should be station t. They became interested how they should choose these stations s, f, t so that the number Grisha will count is as large as possible. They asked you for help.
The first line contains two integers n and q (2 ≤ n ≤ 105, 1 ≤ q ≤ 105) — the number of stations and the number of days.
The second line contains n - 1 integers p2, p3, ..., pn (1 ≤ pi ≤ n). The integer pi means that there is a route between stations pi and i. It is guaranteed that it's possible to reach every station from any other.
The next q lines contains three integers a, b and c each (1 ≤ a, b, c ≤ n) — the ids of stations chosen by boys for some day. Note that some of these ids could be same.
Print q lines. In the i-th of these lines print the maximum possible number Grisha can get counting when the stations s, t and f are chosen optimally from the three stations on the i-th day.
题意:
对于一个终点站f, 从s出发,和从t出发。经过的相同站有多少
有n个点,n-1条边。m次询问给出3个数 a, b, c。在a, b, c中选择一个终点两个起点,使得共同的站最大。
题解:
由于是一个树,所以就直接建树(点到点的距离设置为1)。暴力跑a,b, c分别为终点的情况。
现在讨论a 为顶点的情况。

那么公共的站点就是公共距离+1。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
#include <map>
#include <stack>
#include <set>
using namespace std;
typedef long long LL;
typedef unsigned long long uLL;
#define ms(a, b) memset(a, b, sizeof(a))
#define pb push_back
#define mp make_pair
const LL INF = 0x7fffffff;
const int inf = 0x3f3f3f3f;
const int mod = 1e9+;
const int maxn = +;
const int DEG = ;
struct node
{
int to, next;
int w;
}edge[*maxn];
int head[maxn], tol, flag[maxn];
void init() {
tol = ;
ms(head, -);
ms(flag, );
}
void addedge(int u, int v, int w)
{
edge[tol].to = v;
edge[tol].next = head[u];
edge[tol].w = w;
head[u] = tol++;
}
int fa[maxn][DEG];
int DD[maxn];
int deg[maxn];
void bfs(int root)
{
queue<int> que;
deg[root] = ;
fa[root][] = root;
DD[root] = ;
que.push(root);
while(!que.empty()){
int tmp = que.front();
que.pop();
for(int i = ;i<DEG;i++){
fa[tmp][i] = fa[fa[tmp][i-]][i-];
}
for(int i = head[tmp];i!=-;i=edge[i].next){
int v = edge[i].to;
if(v == fa[tmp][]) continue;
deg[v] = deg[tmp]+;
fa[v][] = tmp;
DD[v] = DD[tmp]+edge[i].w;
que.push(v);
}
}
}
int LCA(int u, int v){
int ans = ;
if(deg[u]>deg[v]) swap(u, v);
int hu = deg[u], hv = deg[v];
int tu = u, tv = v;
for(int det = hv - hu, i=;det;det>>=, i++){
if(det&){
tv = fa[tv][i];
}
}
if(tu==tv){
return tu;
}
for(int i = DEG - ;i>=;i--){
if(fa[tu][i] == fa[tv][i]) continue;
tu = fa[tu][i];
tv = fa[tv][i];
}
return fa[tu][];
}
int DIS(int u, int v)
{
return DD[u] + DD[v] - *DD[LCA(u, v)];
}
void solve()
{
int n, q;
cin >> n >> q;
for(int i = ;i<=n;i++){
int x;cin >> x;
addedge(i, x, );
addedge(x, i, );
flag[x] = ;
}
int root;
for(int i = ;i<=n;i++){
if(!flag[i]){
root = i;
break;
}
}
// cout << root << endl;
bfs(root);
for(int i = ;i<q;i++){
int a, b, c;
cin >> a >> b >> c;
int ans = ;
ans = max(ans, (DIS(b, a)+DIS(c, a)-DIS(b, c))/);
ans = max(ans, (DIS(a, b)+DIS(c, b)-DIS(a, c))/);
ans = max(ans, (DIS(a, c)+DIS(b, c)-DIS(a, b))/);
cout << ans+ << endl;
}
}
int main() {
#ifdef LOCAL
freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
#endif
ios::sync_with_stdio();
cin.tie();
init();
solve();
}
Codeforecs Round #425 D Misha, Grisha and Underground (倍增LCA)的更多相关文章
- Codeforces Round #425 (Div. 2) Misha, Grisha and Underground(LCA)
Misha, Grisha and Underground time limit per test 2 seconds memory limit per test 256 megabytes inpu ...
- Codeforces 832D: Misha, Grisha and Underground 【LCA模板】
题目链接 模板copy from http://codeforces.com/contest/832/submission/28835143 题意,给出一棵有n个结点的树,再给出其中的三个结点 s,t ...
- Codeforces 832D - Misha, Grisha and Underground
832D - Misha, Grisha and Underground 思路:lca,求两个最短路的公共长度.公共长度公式为(d(a,b)+d(b,c)-d(a,c))/2. 代码: #includ ...
- Codeforces 832 D Misha, Grisha and Underground
Misha, Grisha and Underground 题意:Misha 和 Grisha 是2个很喜欢恶作剧的孩子, 每天早上 Misha 会从地铁站 s 通过最短的路到达地铁站 f, 并且在每 ...
- D. Misha, Grisha and Underground 树链剖分
D. Misha, Grisha and Underground 这个题目算一个树链剖分的裸题,但是这个时间复杂度注意优化. 这个题目可以选择树剖+线段树,时间复杂度有点高,比较这个本身就有n*log ...
- Codeforces Round #425 (Div. 2) Problem D Misha, Grisha and Underground (Codeforces 832D) - 树链剖分 - 树状数组
Misha and Grisha are funny boys, so they like to use new underground. The underground has n stations ...
- Codeforces Round #425 (Div. 2) D.Misha, Grisha and Underground
我奇特的脑回路的做法就是 树链剖分 + 树状数组 树状数组是那种 区间修改,区间求和,还有回溯的 当我看到别人写的是lca,直接讨论时,感觉自己的智商收到了碾压... #include<cmat ...
- 【树链剖分】【dfs序】【LCA】【分类讨论】Codeforces Round #425 (Div. 2) D. Misha, Grisha and Underground
一棵树,q次询问,每次给你三个点a b c,让你把它们选做s f t,问你把s到f +1后,询问f到t的和,然后可能的最大值是多少. 最无脑的想法是链剖线段树……但是会TLE. LCT一样无脑,但是少 ...
- 【 Codeforces Round #425 (Div. 2) D】Misha, Grisha and Underground
[Link]:http://codeforces.com/contest/832/problem/D [Description] 给你一棵树; 然后给你3个点 让你把这3个点和点s,t,f对应; 然后 ...
随机推荐
- 【python+selenium自动化】使用pytest+allure2完成自动化测试报告的输出
pytest的pytest-html插件是一个很方便的测试报告,运行自动化测试用例时,pytest后加上参数即可 allure是一个测试报告的框架,相比pytest-html的优势就是“逼格” 他的优 ...
- XMind8激活为Pro教程 - Windows&Mac
本教程用于激活XMind(思维导图制作软件),仅限于个人学习使用. 目前本人激活的版本是xmind8-up6版本,其他更高版本不保证能适用. Windows步骤: 1.英文官网下载客户端并安装(不能用 ...
- mysql 主从 设置
总结:1.如果是虚拟克隆mysql 请注意auto.cnf的uuid保证不一样,即删除auto.cnf 重新启动即可2.默认安装的mysql配置文件mysqld.cnf可能绑定了127.0.0.1 只 ...
- JAVA总结--JDK版本区别
jdk1.5的新特性: 1.泛型 2.自动拆箱装箱 3.foreach 4.静态导入(Static import) 此外,枚举.元数据(Metadata).线程池.Java Generics ...
- CentOS7 破解登录密码
1.重启系统,在出现下面这个界面时按e 2.进入之后方向键的下,找到“LANG=en_US.UTF-8",在这个命令后面输入“rd.break",完成之后按ctrl+x进入紧急救援 ...
- P2517 [HAOI2010]订货(dp)
P2517 [HAOI2010]订货 设$f[i][j]$表示第$i$个月,库存为$j$的最小代价 枚举上个月的库存$k$,那么$f[i][j]=f[i-1][k]+(j+U[i]-k)*D[i]+j ...
- 树莓派上编译安装python3.6
1.更新树莓派系统 sudo apt-get update sudo apt-get upgrade -y 2.安装python依赖环境 sudo apt-get install build-esse ...
- 解决Vscode编辑器不能打开多标签页问题
问题描述:编辑代码时,初用vscode,不能打开多个文件:每打开一个文件,都会替换前面一个文件标签,很不方便切换编码: 想要的效果: 解决方式: 方法一: 找到setting.json文件,最外层花括 ...
- tomcat闪屏是jdk JAVA_HOEM环境变量配置问题
JAVA_HOME=D:\jdk.18
- Python单例模式的设计与实现【完美版】
目录 1. 按 2. 本文地址 3. 通过继承单例父类来实现 4. 使用装饰器实现 4.1. 懒汉式 4.2. 饿汉式 4.2.1. 未加锁版 4.2.2. 加锁版 1. 按 众所周知,对象是解决继承 ...