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对应; 然后 ...
随机推荐
- Spring Boot 之 Redis
一.pom.xml引入依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifac ...
- ecshop启用gzip后,后台不能打开不能访问的问题
上传测试的时候,站点显示无法打开.随后我用网址打开根目录的robots文件.图片.静态页···全部可以正常打开··· 我尴尬···一一检查后,我就怀疑是不是客户当初设置gzip压缩的问题了.但连后台都 ...
- 使用MarkDown的编辑器
今天找到了一个比较全的markdown格式说明http://www.appinn.com/markdown/#precode,特别是代码标注的时候 多行的时候 使用 ... ... .. .. 可以把 ...
- 14 (H5*) JS第4天 函数、作用域、预解析
目录 1:函数的其他定义 2:函数作为参数 3:函数作为返回值 4:作用域 5:作用域链 6:预解析 7:预解析分段 复习 <script> /* * 复习: * 函数:把一些重复的代码封 ...
- java二周的学习总结
一转眼二周就过去了,个人觉得虽然java和C语言有差异,但差别并不大,因为语法语句方面都是差不多的,因为我上个学期并没有很认真的学好C语言,所以我这个学期更希望学好java,java方面还是挺有趣的, ...
- mysql索引与补充
一, 什么是索引 为什么要有索引? 一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很少出现性能问题,在生产环境中,我们遇到最多的,也是最容易出问题的,还是一些复杂的查询操作,因此 ...
- void die(const char *msg)
void die(const char *msg) { perror(msg); exit(errno); }
- [Poj2349]Arctic Network(二分,最小生成树)
[Poj2349]Arctic Network Description 国防部(DND)要用无线网络连接北部几个哨所.两种不同的通信技术被用于建立网络:每一个哨所有一个无线电收发器,一些哨所将有一个卫 ...
- APKMirror - 直接下载google play里的应用
APKMirror - Free APK Downloads - Download Free Android APKs #APKPLZ https://www.apkmirror.com/
- Angular 一个简单的指令实现 阻止事件扩散
//指令定义 @Directive({ selector: `click-stop-propagation` events: 'stopClick($event)' }) class ClickSto ...