Cod sursa(job #3353686)

Utilizator AlexOprescu21Oprescu Alexandru AlexOprescu21 Data 9 mai 2026 16:52:00
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.65 kb
#include <bits/stdc++.h>

using namespace std;

ifstream fin("lca.in");
ofstream fout("lca.out");

int const NMAX = 1e5 + 1;
int const LOGMAX = 18;

vector<int> fii[NMAX];
int euler[2*NMAX];
int nivele[2*NMAX];
int aparitii[NMAX];
int rmq[2*NMAX][LOGMAX];
int contor = 0;

void parcurgere(int nod, int nivel){
    aparitii[nod] = contor;
    euler[contor] = nod;
    nivele[contor++] = nivel;
    for(int fiu : fii[nod]){
        parcurgere(fiu, nivel+1);
        euler[contor] = nod;
        nivele[contor++] = nivel;
    }
}

void preprocesare(){
    for(int i = 0; i < contor; i++){
        rmq[i][0] = i;
    }
    for(int j = 1; (1<<j) <= contor; j++){
        for(int i = 0; i+(1<<j) - 1 < contor; i++ ){
            if(nivele[rmq[i][j - 1]] < nivele[rmq[i + (1 << (j - 1))][j - 1]])
                rmq[i][j] = rmq[i][j - 1];
            else
                rmq[i][j] = rmq[i + (1 << (j - 1))][j - 1];
        }
    }
}

int interogare(int a, int b){
    int first_a = aparitii[a];
    int first_b = aparitii[b];
    if(first_a > first_b)
        swap(first_a, first_b);
    int lungime = first_b - first_a + 1;
    int l = log2(lungime);
    if(nivele[rmq[first_a][l]] < nivele[rmq[first_b - (1<<l) + 1][l]])
        return euler[rmq[first_a][l]];
    else
        return euler[rmq[first_b - (1<<l) + 1][l]];
}

int main(){
    int n, m;
    fin>>n>>m;
    for(int i = 2; i<=n; i++){
        int x;
        fin>>x;
        fii[x].push_back(i);
    }
    parcurgere(1, 0);
    preprocesare();
    for(int i = 0; i < m; i++){
        int a, b;
        fin>>a>>b;
        fout<<interogare(a, b)<<"\n";
    }
}