Cod sursa(job #2890969)

Utilizator Katherine456719Swan Katherine Katherine456719 Data 17 aprilie 2022 11:24:26
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.72 kb
//LCA
#include <fstream>
#include <vector>

using namespace std;

const int MAX = 100014;
const int LOGMAX = 22;

struct st {
    int nivel , nod ;
};

st q[ MAX << 1];

vector < int > gr[MAX];
int now , first [MAX] , R[LOGMAX][MAX << 2] , log[MAX << 1] ;
void dfs(int nod, int lvl){
    ++ now ;
    q [now].nivel = lvl ;
    q [now].nod = nod ;
    first[nod] = now ;
    for ( auto x : gr[nod] )
    {
        dfs (x, lvl + 1) ;
        ++ now ;
        q [now].nivel = lvl ;
        q [now].nod = nod ;
    }
}
void RMQ ( int n )
{
    log[1] = 0 ;
    for (int i = 2 ; i <= n ; ++ i )
        log[i] = log[i>>1] + 1 ;
    for (int i = 1 ; i <= n ; ++ i)
        R [0][i] = i ;
    for (int i = 1 ; (1 << i) <= n ; ++ i)
        for (int j = 1 ; j <= n - (1<<i) + 1 ; ++ j){
            int l = 1 << ( i - 1 ) ;
            R[i][j] = R[i-1][j] ;
            if ( q[R[i][j]].nivel > q[R[i-1][j+l]].nivel )
                R[i][j] = R[i-1][j+l] ;
        }
}
int lca(int x ,int y)
{
    int a = first [ x ] ;
    int b = first [ y ] ;
    if ( a > b )
        swap ( a , b ) ;
    int diff = b - a + 1 ;
    int lg = log [ diff ] ;
    int sol = R [ lg ] [ a ] ;
    int sh = diff - (1 << lg) ;
    if ( q [ sol ].nivel > q[ R [ lg ] [ a + sh ] ].nivel )
        sol = R [ lg ] [ a + sh ];
    return q [ sol ].nod ;
}
int main( )
{
    ifstream fin("lca.in");
    ofstream fout("lca.out");
    int n , m ;
    fin >> n >> m ;
    for (int i = 2 ; i <= n ; ++ i){
        int x ;
        fin >> x;
        gr[x].push_back(i) ;
    }
    dfs (1, 0) ;
    RMQ (now) ;
    while (m--){
        int x, y ;
        fin >> x >> y ;
        fout << lca(x ,y) << '\n' ;
    }
    return 0;
}