Cod sursa(job #2083739)

Utilizator lucian666Vasilut Lucian lucian666 Data 8 decembrie 2017 03:55:57
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.04 kb
#include <fstream>
#include <algorithm>
#include <vector>
#include <cmath>


#define DIM 100009
#define LG 20
#define pb push_back

using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");


int n , m , Euler[ DIM * 2 ] , niv[ DIM * 2 ] , First[ DIM ] , K;
int dp[ 2 * DIM][ LG * 2];

vector < int > G[DIM];
typedef vector < int >:: iterator IT;

void Read();
void Dfs( int start , int lev );
void Rmq();
void Lca();

int main()
{

    Read();
    Dfs(1,0);

    n = 2 * n - 1;

    Rmq();
    Lca();

    return 0;

}

void Read()
{

    in >> n >> m ;

    for( int i = 2; i <=n ; i++)
    {

        int x;
        in >> x;
        G[x].pb(i);

    }

}


void Dfs( int nod , int level )
{

    Euler[++K] = nod;
    niv[ K ] = level;
    First[ nod] = K;

    for( IT i = G[nod].begin() ; i!=G[nod].end() ; ++i)
    {

        Dfs(*i,level + 1 );
        Euler[++K] = nod;
        niv[K] = level;

    }


}

void Rmq()
{

    for( int i = 1  ;i <=n ; i++)
        dp[i][0] = i;

    int k  = 0;

    while( ( 1 << k ) <=n )
        ++k;

    --k;

    for( int j = 1 ; j <=k ; j++)
    {

        for( int i = 1;  i<=n ; i++)
        {

            dp[i][j] = dp[i][j-1];

            if( ( i + ( 1 << ( j - 1 ) ) <=n ) && niv[ dp[i][j] ] > niv[ dp[ i + ( 1 << ( j - 1 ) ) ][j-1]] )
                dp[i][j] = dp[ i + ( 1 << ( j -1 ) )][ j - 1 ];

        }

    }

}

void Lca()
{

    for( ; m ; --m)
    {

        int X , Y;
        int x , y;
        in >> X >> Y;

        x = First[X];
        y = First[Y];

        if( x > y )
            swap(x,y);

        if( x ==  y )
        {

            out << Euler[dp[x][0]] << '\n';
            continue;
        }

        int k = 0;
        k = (int) floor( log( y - x )/log(2));

        if( niv[dp[x][k]] <=  niv[dp[ y - ( 1 << k ) + 1][k]] )
            out << Euler[dp[x][k]] << '\n';
        else
            out << Euler[dp[ y - ( 1 << k ) + 1 ][k]] << '\n';


    }

}