Cod sursa(job #2906757)

Utilizator rapidu36Victor Manz rapidu36 Data 27 mai 2022 12:28:46
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.89 kb
#include <fstream>

using namespace std;

const int N = 1e5;
const int L = 17;

int t[L][N], nivel[N+1], log[N+1], n;

void calcul_t()
{
    for (int e = 1; e < L; e++)
    {
        for (int i = 1; i <= n; i++)
        {
            t[e][i] = t[e-1][t[e-1][i]];///stramsoul de ordin 2^e=stramosul de ord 2^(e-1) al
            ///stramosului de ordinul 2^(e-1)
        }
    }
}

void nivelul(int x)
{
    if (nivel[x] != 0)
    {
        return;
    }
    nivelul(t[0][x]);
    nivel[x] = 1 + nivel[t[0][x]];
}

void calcul_nivel()
{
    nivel[1] = 1;
    for (int i = 2; i <= n; i++)
    {
        nivelul(i);
    }
}

void calcul_log()
{
    log[1] = 0;
    for (int i = 2; i <= n; i++)
    {
        log[i] = 1 + log[i/2];
    }
}

int stramos(int x, int ord)
{
    ///returneaza stramosul de ordinul ord al lui x
    int e = 0;
    while (ord != 0)
    {
        if (ord % 2 != 0)
        {
            x = t[e][x];
        }
        e++;
        ord /= 2;
    }
    return x;
}

int lca(int x, int y)
{
    int e = log[nivel[x]];
    while (e >= 0)
    {
        if (t[e][x] != t[e][y])
        {
            x = t[e][x];
            y = t[e][y];
        }
        e--;
    }
    return t[0][x];///stiu ca t[0][x] = t[0][y]
}

int main()
{
    ifstream in("lca.in");
    ofstream out("lca.out");
    int nq;
    in >> n >> nq;
    for (int i = 2; i <= n; i++)
    {
        in >> t[0][i];
    }
    calcul_t();
    calcul_nivel();
    calcul_log();
    for (int i = 0; i < nq; i++)
    {
        int x, y;
        in >> x >> y;
        if (nivel[x] > nivel[y])
        {
            swap(x, y);
        }
        y = stramos(y, nivel[x] - nivel[y]);
        if (y == x)
        {
            out << x << "\n";
        }
        else
        {
            out << lca(x, y) << "\n";
        }
    }
    return 0;
}