codeoforces832D
来源:互联网 发布:山东大学网络教育期末考试 编辑:程序博客网 时间:2024/06/17 04:17
#include <bits/stdc++.h>using namespace std;const int N = 1E5 + 9, lg = 18;int deep[N], par[lg][N], a, b, c, n, q;#define pb push_backvector<int>g[N];void dfs(int u){ for(auto it:g[u]) { deep[it] = deep[u] + 1; par[0][it] = u; dfs(it); }}void init(){ for(int k = 0;k + 1 < lg;k ++) { for(int v = 0;v < n;v ++) { if(par[k][v] < 0) par[k + 1][v] = -1; else par[k + 1][v] = par[k][par[k][v]]; } }}int lca(int u,int v){ if(deep[u] > deep[v]) swap(u, v); for(int k = 0;k < lg;k ++) { if(deep[v] - deep[u] >> k & 1) { v = par[k][v]; } } if(u == v) return u; for(int k = lg - 1;k >= 0;k --) { if(par[k][u] != par[k][v]) { u = par[k][u], v = par[k][v]; } } return par[0][u];}int solve(int s ,int t, int f){ int ans = 0;bool is1 = lca(f, s) == f, is2 = lca(f, t) == f;if(is1 != is2) return 1;if(is1)ans = deep[ lca(s, t) ] - deep[ f ];else if(lca(f, s) != lca(f, t))ans = deep[ f ] - max(deep[ lca(f, s) ], deep[ lca(f, t) ]);elseans = deep[ f ] + deep[ lca(s, t) ] - 2 * deep[ lca(f, t) ];//难点return ans + 1;}int main(){ scanf("%d%d",&n,&q); for(int i = 1;i < n;i ++) { scanf("%d",&a); a --; g[a].pb(i); } memset(par, -1, sizeof(par)); dfs(0); init(); while(q --) { scanf("%d%d%d",&a,&b,&c); a--,b--,c--; int k1 = solve(a, b, c); int k2 = solve(c, b, a); int k3 = solve(c, a, b); printf("%d\n",max({k1,k2,k3})); } return 0;}
很套路的一题,感觉难点是判断树的lca结构那里。
阅读全文
1 0