Cod sursa(job #3142942)

Utilizator dobreraduDobre Radu Fabian dobreradu Data 26 iulie 2023 11:05:15
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.37 kb
#include <bits/stdc++.h>

using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
const int NMAX = 100001;
vector <int> daddy[NMAX];
int dp[18][NMAX], level[NMAX];
void depth( int nod ){
    for( int i = 0; i < daddy[nod].size(); i++ ){
        level[daddy[nod][i]] = level[nod]+1;
        depth( daddy[nod][i] );
    }
}
int same_depth( int a, int b ){
    for( int lg = 17 ; lg >= 0; lg-- )
        if( (1 << lg) <= level[a] - level[b] )
            a = dp[lg][a];
    return a;
}
void initializare( int n ){
    for( int lg = 1; (1 << lg) <= n; lg++ )
        for( int i = 2; i <= n; i++ )
            dp[lg][i] = dp[lg-1][dp[lg-1][i]];
}
int lca( int a, int b ){
    if( level[a] > level[b] )
        a = same_depth(a, b);
    else
        b = same_depth(b, a);
    if( a == b )
        return a;

    for( int lg = 17; lg >= 0; lg-- ){
        if( dp[lg][a] != dp[lg][b] ){
            a = dp[lg][a];
            b = dp[lg][b];
        }
    }
    return dp[0][a];
}
int main()
{
    int n, m;
    in >> n >> m;
    for( int i = 2; i <= n; i++ ){
        int a;
        in >> a;
        daddy[a].push_back(i);
        dp[0][i] = a;
    }
    initializare(n);
    level[1] = 1;
    depth(1);
    for( int i = 0; i < m; i++ ){
        int a, b;
        in >> a >> b;
        out << lca(a, b) << "\n";
    }
    return 0;
}