Cod sursa(job #3177821)

Utilizator SSKMFSS KMF SSKMF Data 30 noiembrie 2023 09:16:10
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.28 kb
#include <fstream>
#include <vector>
using namespace std;

ifstream cin ("lca.in");
ofstream cout ("lca.out");

int prima_aparitie[100001] , adancime[100001];
vector <int> adiacenta[100001];
vector <int> tabel[18];

void Parcurgere (const int nod_actual)
{
    prima_aparitie[nod_actual] = tabel[0].size();
    tabel[0].push_back(nod_actual);
    
    if (!adiacenta[nod_actual].size())
        { tabel[0].push_back(nod_actual); }

    for (auto nod_vecin : adiacenta[nod_actual])
        { adancime[nod_vecin] = adancime[nod_actual] + 1; Parcurgere(nod_vecin); tabel[0].push_back(nod_actual); }
}

int main ()
{
    int numar_noduri , numar_intrebari;
    cin >> numar_noduri >> numar_intrebari;

    for (int nod_actual = 2 , nod_sursa ; nod_actual <= numar_noduri ; nod_actual++)
        { cin >> nod_sursa; adiacenta[nod_sursa].push_back(nod_actual); }

    Parcurgere(1);

    for (unsigned int exponent = 1 , putere = 2 ; putere <= tabel[0].size() ; exponent++ , putere <<= 1) {
        tabel[exponent].resize(tabel[0].size() - putere + 1);
        for (unsigned int indice = 0 ; indice < tabel[exponent].size() ; indice++) {
            tabel[exponent][indice] = (adancime[tabel[exponent - 1][indice]] <= adancime[tabel[exponent - 1][indice + (putere >> 1)]] ? tabel[exponent - 1][indice] : tabel[exponent - 1][indice + (putere >> 1)]);
        }
    }

    while (numar_intrebari--)
    {
        int nod_1 , nod_2;
        cin >> nod_1 >> nod_2;

        int stanga = min(prima_aparitie[nod_1] , prima_aparitie[nod_2]) , dreapta = max(prima_aparitie[nod_1] ,prima_aparitie[nod_2]) , exponent = 0;
        if ((1 << (exponent | 16)) <= dreapta - stanga + 1) { exponent |= 16; }
        if ((1 << (exponent | 8)) <= dreapta - stanga + 1) { exponent |= 8; }
        if ((1 << (exponent | 4)) <= dreapta - stanga + 1) { exponent |= 4; }
        if ((1 << (exponent | 2)) <= dreapta - stanga + 1) { exponent |= 2; }
        if ((1 << (exponent | 1)) <= dreapta - stanga + 1) { exponent |= 1; }
        
        const int putere = (1 << exponent);
        cout << (adancime[tabel[exponent][stanga]] < adancime[tabel[exponent][dreapta - putere + 1]] ? tabel[exponent][stanga] : tabel[exponent][dreapta - putere + 1]) << '\n';
    }

    cout.close(); cin.close();
    return 0;
}