Cod sursa(job #2970853)

Utilizator iordache.bogdanIordache Ioan-Bogdan iordache.bogdan Data 25 ianuarie 2023 23:19:15
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.61 kb
/*
 * O(NlogN + QlogN)
 */
#include <fstream>
#include <vector>
using namespace std;

const int MAX_LOG = 18;
const int MAX_N = 100005;

int N, Q;
vector<int> arbore[MAX_N];
int parinte[MAX_N], nivel[MAX_N];
int p_curent, p_start[MAX_N], p_end[MAX_N];
int stramos[MAX_LOG][MAX_N];

void dfs(int nod, int nvl = 1)
{
    nivel[nod] = nvl;
    p_start[nod] = ++p_curent;
    for (int fiu : arbore[nod])
    {
        dfs(fiu, nvl + 1);
    }
    p_end[nod] = ++p_curent;
}

bool este_stramos(int x, int y)
{
    // return true <=> x este stramos al lui y
    return p_start[x] <= p_start[y] && p_end[y] <= p_end[x];
}

void calculeaza_stramosi()
{
    for (int nod = 1; nod <= N; ++nod)
    {
        stramos[0][nod] = parinte[nod];
    }
    for (int p = 1; p < MAX_LOG; ++p)
    {
        for (int nod = 1; nod <= N; ++nod)
        {
            stramos[p][nod] = stramos[p - 1][stramos[p - 1][nod]];
        }
    }
}

int lca(int x, int y)
{
    if (este_stramos(x, y))
    {
        return x;
    }
    if (este_stramos(y, x))
    {
        return y;
    }
    for (int p = MAX_LOG - 1; p >= 0; --p)
    {
        int z = stramos[p][x];
        if (z != 0 && !este_stramos(z, y))
        {
            x = z;
        }
    }
    return stramos[0][x];
}

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

    fin >> N >> Q;
    for (int nod = 2; nod <= N; ++nod)
    {
        fin >> parinte[nod];
        arbore[parinte[nod]].push_back(nod);
    }

    p_curent = 0;
    dfs(1);

    calculeaza_stramosi();

    while (Q--)
    {
        int x, y;
        fin >> x >> y;
        fout << lca(x, y) << "\n";
    }

    return 0;
}