Cod sursa(job #3206803)

Utilizator VerestiucAndreiVerestiuc Andrei VerestiucAndrei Data 24 februarie 2024 10:20:20
Problema Lowest Common Ancestor Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.39 kb
#include <bits/stdc++.h>
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]) // ne asiguram ca level[x] < level[y]
            swap(x, y);
        y = go_up(y, level[y] - level[x]);
        if(x == y) {
            fout << x << "\n";
            continue;
        }
        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;
}