Cod sursa(job #2738514)

Utilizator BAlexandruBorgovan Alexandru BAlexandru Data 5 aprilie 2021 23:05:04
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.41 kb
#include <fstream>
#include <vector>

using namespace std;

ifstream f("lca.in");
ofstream g("lca.out");

int n, m;

int depth[100001];

int dp[100001][17];

int log2[100001];

vector < int > adj[100001];

void dfs(int node, int parent, int d)
{
    depth[node] = d;

    dp[node][0] = parent;

    for (auto it : adj[node])
        dfs(it, node, d + 1);
}

int lca(int x, int y)
{
    if (x == y)
        return x;

    if (depth[x] < depth[y])
        swap(x, y);

    if (depth[x] != depth[y])
    {
        for (int i = log2[depth[x]]; i >= 0; i--)
            if (depth[x] - (1 << i) >= depth[y])
                x = dp[x][i];

        if (x == y)
            return x;
    }

    for (int i = log2[depth[x]]; i >= 0; i--)
        if (depth[x] - (1 << i) >= 0 && dp[x][i] != dp[y][i])
        {
            x = dp[x][i];
            y = dp[y][i];
        }

    return dp[x][0];
}

int main()
{
    f >> n >> m;

    for (int node = 2; node <= n; node++)
    {
        int parent; f >> parent;
        adj[parent].push_back(node);
    }

    dfs(1, 0, 0);

    for (int i = 2; i <= n; i++)
        log2[i] = log2[i / 2] + 1;

    for (int i = 1; (1 << i) <= n; i++)
        for (int j = 1; j <= n; j++)
            dp[j][i] = dp[dp[j][i - 1]][i - 1];

    while (m--)
    {
        int x, y; f >> x >> y;
        g << lca(x, y) << "\n";
    }

    return 0;
}