Cod sursa(job #3293841)

Utilizator robert_dumitruDumitru Robert Ionut robert_dumitru Data 12 aprilie 2025 18:38:54
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.56 kb
#include <bits/stdc++.h>
using namespace std;

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

int n, Q, top;
int e[200005], nivel[200005], P[200005], expo[200005], viz[100005], rmq[20][200005];
vector<int> L[100005];

void DFS(int k, int niv)
{
    viz[k] = 1;
    e[++top] = k;
    nivel[top] = niv + 1;
    P[k] = top;
    for (int i : L[k])
        if (viz[i] == 0)
        {
            DFS(i, niv + 1);
            e[++top] = k;
            nivel[top] = niv + 1;
        }
}
void BuildRMQ()
{
    int i, j, A, B, L;
    expo[1] = 0;
    for (i = 2; i <= top; i++)
        expo[i] = 1 + expo[i / 2];
    for (i = 1; i <= top; i++)
        rmq[0][i] = i;
    for (i = 1; i <= expo[top]; i++)
    {
        L = (1 << (i - 1));
        for (j = 1; j <= top - 2 * L + 1; j++)
        {
            A = rmq[i - 1][j];
            B = rmq[i - 1][j + L];
            if (nivel[A] <= nivel[B])
                rmq[i][j] = A;
            else rmq[i][j] = B;
        }
    }

}

int Query(int A, int B)
{
    int exp, L;
    A = P[A]; B = P[B];
    if (A > B) swap(A, B);
    L = B - A + 1;
    exp = expo[L];
    L = (1 << exp);
    A = rmq[exp][A];
    B = rmq[exp][B - L + 1];
    if (nivel[A] <= nivel[B]) return e[A];
    return e[B];
}
int main()
{
    int i, j;
    fin >> n >> Q;
    for (i = 2; i <= n; i++)
    {
        fin >> j;
        L[j].push_back(i);
    }
    DFS(1, 1);
    BuildRMQ();
    while (Q--)
    {
        fin >> i >> j;
        fout << Query(i, j) << "\n";
    }
    return 0;
}