Cod sursa(job #3286648)

Utilizator robert_dumitruDumitru Robert Ionut robert_dumitru Data 14 martie 2025 14:51:24
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.45 kb
#include <bits/stdc++.h>
using namespace std;

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

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

void Euler(int k, int level)
{
    euler[++top] = k;
    P[k] = top;
    nivel[top] = level;
    for (int i : L[k])
    {
        Euler(i, level + 1);
        euler[++top] = k;
        nivel[top] = level;
    }
}
void BuildRMQ()
{
    int i, j, L, A, B;
    e[1] = 0;
    for (i = 2; i <= top; i++)
        e[i] = e[i / 2] + 1;
    for (i = 1; i <= top; i++)
        rmq[0][i] = i;
    for (i = 1; i <= e[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 LCA(int A, int B)
{
    int L, expo;
    A = P[A]; B = P[B];
    if (A > B) swap(A, B);
    expo = e[B - A + 1];
    L = (1 << expo);
    A = rmq[expo][A]; B = rmq[expo][B - L + 1];
    if (nivel[A] <= nivel[B]) return euler[A];
    return euler[B];
}

int main()
{
    int i, j;
    fin >> n >> Q;
    for (i = 2; i <= n; i++)
    {
        fin >> j;
        L[j].push_back(i);
    }
    Euler(1, 1);
    BuildRMQ();
    while (Q--)
    {
        fin >> i >> j;
        fout << LCA(i, j) << "\n";
    }
    return 0;
}