Codeforces Round #425 (Div. 2) D. Misha, Grisha and Underground

来源:互联网 发布:新版淘宝怎么充话费 编辑:程序博客网 时间:2024/06/12 19:11

LCA倍增算法模版



#include <iostream>

#include <cstring>

#include <cstdio>

#include <cmath>

#include <algorithm>

#include <vector>


using namespace std;


const int MaxN = 1e5;


int n, m;

int depth[MaxN + 1];

int f[MaxN + 1][20];

vector<int> g[MaxN + 1];


void dfs(int u, int fa, int deep)

{

    depth[u] = deep;

    for (int i = 0; i < g[u].size(); i++)

    {

        int v = g[u][i];

        if (v == fa)

            continue;

        f[v][0] = u;

        dfs(v, u, deep + 1);

    }

}


void init()

{

    for (int j = 1; (1 << j) <= n; j++)

        for (int i = 1; i <= n; i++)

            f[i][j] = f[f[i][j - 1]][j - 1];

}


int lca(int a, int b)

{

    if (depth[a] < depth[b])

        swap(a, b);

    int d = depth[a] - depth[b];

    for (int i = 0; d; d >>= 1, i++)

        if (d & 1)

            a = f[a][i];

    if (a == b)

        return a;

    for (int i = 19; i >= 0; i--)

        if (f[a][i] != f[b][i])

        {

            a = f[a][i];

            b = f[b][i];

        }

    return f[a][0];

}


int dist(int x, int y)

{

    return depth[x] + depth[y] - 2 * depth[lca(x, y)];

}


int main()

{

    cin >> n >> m;

    for (int i = 2; i <= n; i++)

    {

        int x;

        scanf("%d", &x);

        g[x].push_back(i);

        g[i].push_back(x);

    }

    

    dfs(100);

    init();

    

    while (m--)

    {

        int a, b, c;

        scanf("%d %d %d", &a, &b, &c);

        int l1 = lca(a, b);

        int l2 = lca(b, c);

        int l3 = lca(a, c);

        if (depth[l1] < depth[l2])

            l1 = l2;

        if (depth[l1] < depth[l3])

            l1 = l3;

        printf("%d\n"max(dist(l1, a), max(dist(l1, b), dist(l1, c))) + 1);

    }

    

    return 0;

}

阅读全文
1 0
原创粉丝点击