Cod sursa(job #3290975)

Utilizator David_Popa123Popa David Matei David_Popa123 Data 2 aprilie 2025 17:07:09
Problema Lowest Common Ancestor Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.57 kb
#include <bits/stdc++.h>

using namespace std;

#define MAXN 100000

ifstream fin( "lca.in" );
ofstream fout( "lca.out" );

vector<int> g[MAXN + 1];
int poz[MAXN + 1], niv[2 * MAXN + 1], rmq[20][4 * MAXN + 1], lg2[MAXN + 1], e[2 * MAXN + 1], m;

void dfs( int nod, int h ) {

    e[++m] = nod;
    niv[m] = h;
    poz[nod] = m;

    for( int i : g[nod] ) {
        dfs( i, h + 1 );
        e[++m] = nod;
        niv[m] = h;
    }
}

int lca( int x, int y ) {
    int a, b, lglen, st, dr, ans;
    st = poz[x];
    dr = poz[y];
    if( st > dr )
        swap( st, dr );
    lglen = lg2[dr - st + 1];
    a = rmq[lglen][st];
    b = rmq[lglen][dr - ( 1 << lglen ) + 1];
    if( niv[a] < niv[b] )
        ans = a;
    else
        ans = b;
    return e[ans];
}

int main() {
    int n, x, y, i, q, p, len, j;

    fin >> n >> q;
    for( i = 2; i <= n; i++ ) {
        fin >> x;
        g[x].push_back( i );
        //tata[i] = x;
    }

    dfs( 1, 0 );

    rmq[0][1] = 1;
    for( i = 2; i <= m; i++ ) {
        lg2[i] = lg2[i >> 1] + 1;
        rmq[0][i] = i;
    }

    for( i = 1; ( 1 << i ) < m; i++ )
        for( j = 1; j <= m - ( 1 << i ); j++ ) {
            p = 1 << ( i - 1 );
            rmq[i][j] = rmq[i - 1][j];
            if( niv[rmq[i - 1][j + p]] < niv[rmq[i][j]] )
                rmq[i][j] = rmq[i - 1][j + p];
        }

    for( i = 1; i <= q; i++ ) {
        fin >> x >> y;
        //lca = numarul minim de pe intervalul poz[x] si poz[y] in vectorul niv[]
        fout << lca( x, y ) << '\n';
    }
    return 0;
}