Cod sursa(job #2738527)

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

using namespace std;

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

int n, m;

int depth[100001];

int pos[100001];

int euler[200001], nrEuler;

int log2[200001];

int rmq[200001][18];

vector < int > adj[100001];

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

    euler[++nrEuler] = node;
    pos[node] = nrEuler;

    for (auto it : adj[node])
    {
        dfs(it, d + 1);
        euler[++nrEuler] = node;
        pos[node] = nrEuler;
    }
}

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

    x = pos[x];
    y = pos[y];

    if (x > y)
        swap(x, y);

    int k = log2[y - x + 1];

    if (depth[rmq[x][k]] < depth[rmq[y - (1 << k) + 1][k]])
        return rmq[x][k];
    else
        return rmq[y - (1 << k) + 1][k];
}

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

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

    dfs(1, 0);

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

    for (int i = 1; i <= nrEuler; i++)
        rmq[i][0] = euler[i];

    for (int i = 1; (1 << i) <= nrEuler; i++)
        for (int j = 1; j + (1 << i) - 1 <= nrEuler; j++)
            if (depth[rmq[j][i - 1]] < depth[rmq[j + (1 << (i - 1))][i - 1]])
                rmq[j][i] = rmq[j][i - 1];
            else
                rmq[j][i] = rmq[j + (1 << (i - 1))][i - 1];

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

    return 0;
}