学习参考:传送门
codeforces 832D
学习了某位聚聚的写法、
#include <cstdio>
#include <cstring>
#include <cmath>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <string>
#include <stack>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include <utility>
using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define pill pair<int, int>
#define ft first
#define sd second
#define mst(a, b) memset(a, b, sizeof a)
#define REP(i, x, n) for(int i = x; i <= n; ++i)
const int qq = 1e5 + 10;
const int MOD = 1e9 + 7;
const int DEG = 17;
vector<int> e[qq];
int TimeTag, in[qq], out[qq], dep[qq];
int fa[qq][DEG];
void Dfs(int u) {
in[u] = ++TimeTag;
for(int i = 1; i < DEG; ++i) {
fa[u][i] = fa[fa[u][i - 1]][i - 1];
}
for(int i = 0; i < (int)e[u].size(); ++i) {
int v = e[u][i];
dep[v] = dep[u] + 1;
fa[v][0] = u;
Dfs(v);
}
out[u] = TimeTag;
}
int Lca(int u, int v) {
if(dep[u] < dep[v]) swap(u, v);
for(int i = 0, d = dep[u] - dep[v]; d; ++i, d >>= 1) {
if(d & 1) u = fa[u][i];
}
if(u == v) return u;
for(int i = DEG - 1; i >= 0; --i) {
if(fa[u][i] != fa[v][i]) {
u = fa[u][i], v = fa[v][i];
}
}
return fa[u][0];
}
int Dis(int u, int v) {
return dep[u] + dep[v] - 2 * dep[Lca(u, v)];
}
int main(){
int n, q; scanf("%d%d", &n, &q);
for(int x, i = 2; i <= n; ++i) {
scanf("%d", &x);
e[x].pb(i);
}
Dfs(1);
while(q--) {
int x, y, z; scanf("%d%d%d", &x, &y, &z);
int a = Dis(x, y) + Dis(z, x) - Dis(y, z);
int b = Dis(x, y) + Dis(z, y) - Dis(x, z);
int c = Dis(x, z) + Dis(y, z) - Dis(x, y);
printf("%d\n", max(a, max(b, c)) / 2 + 1);
}
return 0;
}