Cod sursa(job #2907450)

Utilizator Theodor17Pirnog Theodor Ioan Theodor17 Data 30 mai 2022 11:47:47
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.49 kb
#include <fstream>

using namespace std;

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

const int NMAX = 1e5;
int t[17][NMAX + 1], lg2[NMAX + 1], nivel[NMAX + 1], n, m, x, y;

void rmq(){

    for(int i = 1; i <= lg2[n]; i++)
        for(int j = 1; j <= n; j++)
            t[i][j] = t[i - 1][t[i - 1][j]];

}

int calcul_nivel(int x){

    if(nivel[x])
        return nivel[x];

    return 1 + calcul_nivel(t[0][x]);

}

int stramos(int x, int ord){

    int e = 0;
    while(ord){

        if(ord % 2){

            x = t[e][x];

        }

        e++;
        ord >>= 1;

    }

    return x;
}

int lca(int x, int y){

    int e = lg2[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];
}

int main(){

    cin >> n >> m;

    lg2[0] = -1;
    for(int i = 2; i <= n; i++){

        cin >> t[0][i];
        lg2[i] = 1 + lg2[i >> 1];

    }

    rmq();
    nivel[1] = 1;

    for(int i = 2; i <= n; i++)
        nivel[i] = calcul_nivel(i);

    for(int i = 0; i < m; i++){

        cin >> x >> y;
        if(nivel[x] > nivel[y]){

            swap(x, y);

        }

        // x este stramos al lui y?
        y = stramos(y, nivel[y] - nivel[x]);

        if(y == x){

            cout << x << "\n";

        }else{

            cout << lca(x, y) << "\n";

        }

    }

    return 0;
}