Cod sursa(job #3156520)

Utilizator vladutzu_finutzuVlad Cacenschi vladutzu_finutzu Data 11 octombrie 2023 18:26:54
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.6 kb
#include <fstream>
#include <vector>
#include <climits>
using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");
vector<vector<int>> children;
vector<int> l, pos, logg, level;
int min_level(int a, int b){
    return (level[l[a]] < level[l[b]] ? a : b);
}
void dfs(int nod, int L){
    l.push_back(nod);
    pos[nod] = l.size() - 1;
    level[nod] = L;

    for(int child:children[nod]){
        dfs(child, L+1);
        l.push_back(nod);
    }
}

vector<vector<int>> RMQ(){
    const int n = l.size();
    vector<vector<int>> dp(20, vector<int>(n));

    for(int i=0; i<n; i++)
        dp[0][i] = i;

    for(int j=1; (1<<j) <= n; j++){
        for(int i = n - 1; i >= 0; i--){
            if(i + (1<<(j)) - 1 >= n)
                continue;

            dp[j][i] = min_level(dp[j-1][i], dp[j-1][i + (1<<(j-1))]);
        }
    }

    return dp;
}
int main(){
    int n, q;
    cin>>n>>q;
    pos.resize(n+1, INT_MAX);
    level.resize(n+1);
    children.resize(n+1);

    for(int i=2; i<=n; i++){
        int x;
        cin>>x;
        children[x].push_back(i);
    }
    dfs(1, 0);

    logg.resize(l.size()+1);
    logg[0] = logg[1] = 0;

    for(int i=2; i<=l.size(); i++)
        logg[i] = logg[i/2] + 1;


    vector<vector<int>> dp = RMQ();

    while(q--){
        int x, y;
        cin>>x>>y;

        if(pos[x] < pos[y])
            swap(x, y);

        int size = pos[x] - pos[y] + 1;
        const int sol = min_level(dp[logg[size]][pos[y]], dp[logg[size]][pos[x] - (1<<logg[size]) + 1]);

        cout<<l[sol]<<'\n';
    }
    return 0;
}