Cod sursa(job #2376376)

Utilizator davidbejenariu2David Bejenariu davidbejenariu2 Data 8 martie 2019 15:13:20
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.81 kb
#include <bits/stdc++.h>
#define NMAX 100005

using namespace std;

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

int N;
int nrq;

vector <int> Ad[NMAX];

int M;
int euler[2*NMAX];
int level[NMAX];
int poz[NMAX];

int rmq[30][2*NMAX];
int lg[2*NMAX];

void DFS( int nod, int lvl )
{
    int i, w;

    euler[++M] = nod;

    if ( poz[nod] == 0 )
    {
        level[nod] = lvl;
        poz[nod] = M;
    }

    for ( i = 0; i < Ad[nod].size(); ++i )
    {
        w = Ad[nod][i];

        DFS( w, lvl + 1 );

        euler[++M] = nod;
    }
}

void gen_euler()
{
    DFS( 1, 1 );
}

void RMQ()
{
    int i, j, a, b;

    for ( i = 1; i <= M; ++i )
         rmq[0][i] = euler[i];

    for ( i = 2; i <= M; ++i )
         lg[i] = lg[i/2] + 1;

    for ( i = 1; ( 1 << i ) <= M; ++i )
         for ( j = 1; j + ( 1 << i ) - 1 <= M; ++j )
         {
             a = rmq[ i - 1 ][ j ];
             b = rmq[ i - 1 ][ j + ( 1 << ( i - 1 ) ) ];

             if ( level[a] < level[b] )
                 rmq[i][j] = a;
             else rmq[i][j] = b;
         }
}

int LCA( int x, int y )
{
    int a, b;
    int k, sol;

    a = poz[x];
    b = poz[y];

    if ( a > b ) swap( a, b );

    k = lg[b-a+1];
    sol = rmq[k][a];

    if ( level[ rmq[k][a] ] > level[ rmq[k][ b - ( 1 << k ) + 1 ] ] )
        sol = rmq[k][ b - ( 1 << k ) + 1 ];

    return sol;
}

void read()
{
    int i, x, y;

    fin >> N >> nrq;

    for ( i = 2; i <= N; ++i )
    {
        fin >> x;

        Ad[x].push_back( i );
    }

    gen_euler();
    RMQ();

    for ( i = 1; i <= nrq; ++i )
    {
        fin >> x >> y;

        fout << LCA( x, y ) << '\n';
    }

    fin.close();
}

int main()
{
    read();

    fout.close();

    return 0;
}