Cod sursa(job #3155804)

Utilizator vladutzu_finutzuVlad Cacenschi vladutzu_finutzu Data 9 octombrie 2023 19:05:09
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.43 kb
#include <fstream>
#include <vector>
using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");
int n, q;
vector<vector<int>> dp, children;
vector<int> D;
void dfs(int nod, int depth){
    if(nod != 1){
        int p=2;
        for(int k=1; p<=depth; k++){
            dp[nod][k] = dp[dp[nod][k-1]][k-1];
            p *= 2;
        }
    }

    D[nod] = depth;

    for(int child:children[nod])
        dfs(child, depth+1);
}
int level(int x, int l){
    int sol = x;
    int p = l - D[x], k=0;

    while(p and sol > 0){
        if(p % 2)
            sol = dp[sol][k];
        
        p /= 2;
        k++;
    }

    return (sol > 0 ? sol : 0);
}
int querry(int a, int b){
    if(D[a] < D[b])
        b = level(b, D[a]);
    
    else a = level(a, D[b]);

    int l = 0, r = D[a], sol = -1;

    while(l <= r){
        int mid = (l + r) / 2;
        int nod = level(a, mid);
        if(nod == level(b, mid))
            sol = nod, l = mid + 1;
        
        else r = mid - 1;
    }

    return sol;
}
int main(){
    cin>>n>>q;
    dp.resize(n+1, vector<int>(20, -1));
    children.resize(n+1);
    D.resize(n+1);

    for(int i=2; i<=n; i++){
        cin>>dp[i][0];
        children[dp[i][0]].push_back(i);
    }
    
    dfs(1, 0);
    // cout<<level(5, 2);
    while(q--){
        int a, b;
        cin>>a>>b;
        cout<<querry(a, b)<<"\n";
    }
    return 0;
}