Cod sursa(job #3170091)

Utilizator chiriacandrei25Chiriac Andrei chiriacandrei25 Data 16 noiembrie 2023 19:49:47
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.38 kb
#include <fstream>

using namespace std;

const int Nmax = 100005;

int rmq[17][Nmax]; // rmq[i][nod] = stramosul 2^i al lui nod
int level[Nmax];

int go_up(int nod, int steps) {
    // operatii pe biti ca sa facem O(nr_biti_1)
    for(int i = 16; i >= 0; i--) {
        if((1 << i) <= steps) {
            nod = rmq[i][nod];
            steps -= (1 << i);
        }
    }
    return nod;
}

int find_level(int nod) {
    if(level[nod]) {
        return level[nod];
    }
    level[nod] = 1 + find_level(rmq[0][nod]);
    return level[nod];
}

int main() {
    int n, m;
    ifstream fin("lca.in");
    ofstream fout("lca.out");
    fin >> n >> m;
    for(int i = 2; i <= n; i++) {
        fin >> rmq[0][i];
    }

    level[1] = 1;
    for(int i = 2; i <= n; i++) {
        level[i] = find_level(i);
    }

    for(int i = 1; i < 17; i++) {
        for(int nod = 1; nod <= n; nod++) {
            rmq[i][nod] = rmq[i - 1][rmq[i - 1][nod]];
        }    
    }
    while(m--) {
        int x, y;
        fin >> x >> y;
        if(level[y] < level[x]) {
            swap(x, y);
        }
        y = go_up(y, level[y] - level[x]);
        for(int i = 16; i >= 0; i--) {
            if(rmq[i][x] != rmq[i][y]) {
                x = rmq[i][x];
                y = rmq[i][y];
            }
        }
        fout << rmq[0][x] << "\n";
    }
    return 0;
}