Cod sursa(job #3214358)

Utilizator ciucelizamariaeliza ciuc ciucelizamaria Data 14 martie 2024 08:41:05
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.66 kb
#include <bits/stdc++.h>

using namespace std;

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

vector<int> L[100005];
int n, rmq[20][200005], e[200005];
int niv[200005], P[100005], k, Q, a[200005];

void Citire()
{
    int x;
    fin >> n >> Q;
    for(int i = 2; i <= n; i++)
    {
        fin >> x;
        L[x].push_back(i);
    }
}

void Euler(int nod, int nivel)
{
    k++;
    niv[k] = nivel;
    a[k] = nod;
    P[nod] = k;
    for(auto i : L[nod])
    {
        Euler(i, nivel + 1);
        k++;
        niv[k] = nivel;
        a[k] = nod;
    }
}

void MakeE()
{
    e[1] = 0;
    for(int i = 2; i <= k; i++)
        e[i] = 1 + e[i / 2];
}

void RMQ()
{
    for(int i = 1; i <= k; i++)
        rmq[0][i] = i;
    int L, A, B;
    for(int i = 1; i <= e[k]; i++)
    {
        L = (1 << i);
        for(int j = 1; j <= k - L + 1; j++)
        {
            A = rmq[i - 1][j];
            B = rmq[i - 1][ j + L / 2];
            if(niv[A] <= niv[B])
                rmq[i][j] = A;
            else
                rmq[i][j] = B;
        }
    }
}

void Rezolvare()
{
    Euler(1, 1);
    MakeE();
    RMQ();
    int x, y, expo, L, A, B;
    while(Q--)
    {
        fin >> x >> y;
        x = P[x];
        y = P[y];
        if(x > y)
            swap(x, y);
        expo = e[y - x + 1];
        L = (1 << expo);
        A = rmq[expo][x];
        B = rmq[expo][y - L + 1];
        if(niv[A] <= niv[B])
              fout << a[A] << "\n";
        else
              fout << a[B] << "\n";
    }
}

int main()
{
    Citire();
    Rezolvare();
    fin.close();
    fout.close();
    return 0;
}