Cod sursa(job #3306463)

Utilizator razvanmrt_06Mariuta Razvan razvanmrt_06 Data 10 august 2025 18:45:20
Problema Lowest Common Ancestor Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.65 kb
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

const int Nmax = 100005;

int n, m, lenE, log2[2*Nmax+5], first[2*Nmax+5];

vector<int> L[Nmax];
vector<pair<int, int>> E; // first = depth && second = nodul;
pair<int, int> dp[Nmax][25];
// dp[i][j] = elem cu depth minim de pe intervalul [i, i + 2^j - 1]
// continand first = depth && second = nodul

void dfs(int nod, int depth){
    E.push_back({depth, nod});
    if(!first[nod]){
        first[nod] = E.size() - 1;
    }
    for(auto son : L[nod]){
        dfs(son, depth+1);
        E.push_back({depth, nod});
    }
}

void preCalc(){
    log2[1] = 0;
    for(int i = 2; i <= 2*Nmax; i++){
        log2[i] = log2[i/2] + 1;
    }
}

void RMQ(){
    for(int i = 0; i < lenE; i++){
        dp[i][0] = E[i];
    }

    for(int p = 1; (1 << p) < lenE; p++){
        for(int i = 0; i + (1 << p) - 1 < lenE; i++){
            dp[i][p] = min(dp[i][p-1], dp[i + (1 << (p-1))][p-1]);
        }
    }
}

int query(int st, int dr){
    int len = dr - st + 1;
    int p = log2[len];
    auto sol = min(dp[st][p], dp[dr - (1 << p) + 1][p]);
    return sol.second;
}

int main(){
    ifstream fin("lca.in");
    ofstream fout("lca.out");
    fin >> n >> m;
    for(int i = 2; i <= n; i++){
        int aux;
        fin >> aux;
        L[aux].push_back(i);
    }
    preCalc();
    dfs(1, 0);
    lenE = E.size();
    RMQ();

    while(m--){
        int x, y;
        fin >> x >> y;
        x = first[x];
        y = first[y];
        if(x > y){
            swap(x, y);
        }
        fout << query(x, y) << "\n";
    }

    return 0;
}