Cod sursa(job #1841625)

Utilizator Tiberiu02Tiberiu Musat Tiberiu02 Data 5 ianuarie 2017 20:15:48
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.46 kb
# include <iostream>
# include <fstream>

# include <vector>
# include <queue>

using namespace std;



# define MAX_N 100000

vector<int> v[1 + MAX_N];
int first[1 + MAX_N];
int depth[1 + MAX_N];
int RMQ[20][1 + 2 * MAX_N];

void calc_euler( int n, int d, int &p )
{
    depth[n] = d;

    first[n] = ++ p;
    RMQ[0][p] = n;

    for ( int s : v[n] ) {
        calc_euler( s, d + 1, p );
        RMQ[0][++ p] = n;
    }
}

void calc_rmq( int N )
{
    for ( int l = 1; ( 1 << l ) <= N; l ++ )
        for ( int i = 1; i + l - 1 <= N; i ++ ) {
            int j = i + ( 1 << l - 1 );
            if ( depth[RMQ[l - 1][i]] < depth[RMQ[l - 1][j]] )
                RMQ[l][i] = RMQ[l - 1][i];
            else
                RMQ[l][i] = RMQ[l - 1][j];
        }
}

int rmq_q( int aa, int bb )
{
    int a = min( aa, bb );
    int b = max( aa, bb );
    int t = b - a;
    int l = 31 - __builtin_clz( t );

    b -= ( 1 << l ) - 1;
    if ( depth[RMQ[l][a]] < depth[RMQ[l][b]] )
        return RMQ[l][a];
    else
        return RMQ[l][b];
}

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

    int n, m, nr, s;
    fin >> n >> m;

    for ( int i = 2; i <= n; i ++ ) {
        fin >> nr;
        v[nr].push_back( i );
    }

    calc_euler( 1, 1, s = 0 );
    calc_rmq( s );

    for ( int i = 0; i < m; i ++ ) {
        int a, b;
        fin >> a >> b;
        fout << rmq_q( first[a], first[b] ) << '\n';
    }

    fin.close();
    fout.close();

    return 0;
}