Cod sursa(job #2660301)

Utilizator Alin_StanciuStanciu Alin Alin_Stanciu Data 18 octombrie 2020 20:09:28
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.49 kb
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

ifstream fin("lca.in");
ofstream fout("lca.out");

int n, m, cnt, T[100001], E[200001], I[100001], Log2[200001];
vector<int> G[100001], Mi[22];

void Euler(int x)
{
    E[++cnt] = x;
    I[x] = cnt;
    for (int y : G[x])
    {
        if (y == T[x])
            continue;
        Euler(y);
        E[++cnt] = x;
    }
}

void Prep()
{
    // Construiesc arborele.
    for (int i = 2; i <= n; ++i)
    {
        G[i].push_back(T[i]);
        G[T[i]].push_back(i);
    }

    // Turul Euler.
    Euler(1);

    // Construiesc Log2 (Log2[x] = [ln(x) / ln(2)]).
    for (int i = 2; i <= 200000; ++i)
        Log2[i] = Log2[i / 2] + 1;

    // Construiesc Mi pentru Rmq.
    Mi[0] = vector<int>(cnt + 1);
    for (int i = 1; i <= cnt; ++i)
        Mi[0][i] = E[i];
    for (int e = 1; e <= Log2[cnt]; ++e)
    {
        Mi[e] = vector<int>(cnt - (1 << e) + 2);
        for (int i = 1; i <= cnt - (1 << e) + 1; ++i)
            Mi[e][i] = min(Mi[e - 1][i], Mi[e - 1][i + (1 << (e - 1))]);
    }
}

int Rmq(int a, int b)
{
    int e = Log2[b - a + 1];
    return min(Mi[e][a], Mi[e][b - (1 << e) + 1]);
}

int main()
{
    fin >> n >> m;
    for (int i = 1; i < n; ++i)
        fin >> T[i + 1];

    Prep();

    for (int i = 1; i <= m; ++i)
    {
        int x, y;
        fin >> x >> y;
        fout << Rmq(min(I[x], I[y]), max(I[x], I[y])) << '\n';
    }

    return 0;
}