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结构那里。