Cod sursa(job #2047347)

Utilizator vladdy47Bucur Vlad Andrei vladdy47 Data 24 octombrie 2017 19:12:49
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.55 kb
# include <bits/stdc++.h>

using namespace std;

const int Nmax = 1e5 + 5;

int n, m, N, x, j, y, euler[2 * Nmax], depth[Nmax], i, rmq[20][2 * Nmax], Log[2 * Nmax], node_pos[Nmax];

vector <int> G[Nmax];

void dfs(int node, int level)
{
    node_pos[node] = N;

    depth[node] = level;

    for (auto &it: G[node])
    {
        euler[++N] = it;
        dfs(it, level + 1);
        euler[++N] = node;
    }

}

void pre_calc_rmq()
{
    for (i = 1; i <= N; ++i)
        rmq[0][i] = euler[i];

    Log[1] = 0;
    for (i = 2; i <= N; ++i)
        Log[i] = Log[i / 2] + 1;

    for (i = 1; i <= Log[N]; ++i)
        for (j = 1; j <= N - (1 << (i - 1)); ++j)
        {
            int a = rmq[i - 1][j], b = rmq[i - 1][j + (1 << (i - 1))];
            if (depth[a] < depth[b]) rmq[i][j] = a;
            else rmq[i][j] = b;
        }
}

void LCA(int x, int y)
{
    int A, B, len;

    x = node_pos[x], y = node_pos[y];
    if (x > y) swap(x, y);

    len = Log[y - x + 1];

    A = rmq[len][x], B = rmq[len][y - (1 << len) + 1];

    if (depth[A] < depth[B]) printf("%d\n", A);
    else printf("%d\n", B);
}

int main ()
{
    freopen("lca.in", "r", stdin);
    freopen("lca.out", "w", stdout);

    scanf("%d %d\n", &n, &m);

    for (i = 2; i <= n; ++i)
    {
        scanf("%d ", &x);
        G[x].push_back(i);
    }

    euler[++N] = 1, depth[1] = 0;
    dfs(1, 0);

    pre_calc_rmq();

    for (i = 1; i <= m; ++i)
    {
        scanf("%d %d\n", &x, &y);
        LCA(x, y);
    }

    return 0;
}