Cod sursa(job #1220720)

Utilizator lucian666Vasilut Lucian lucian666 Data 18 august 2014 12:35:22
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.09 kb
#include <fstream>
#include <algorithm>
#include <vector>
#include <cmath>


#define NMAX 100009
#define LG 20
#define pb push_back

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

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

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



void read();
void dfs( int , int );
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].push_back(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 ; //lucram cu indexii , nu cu valori !!!


    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()
{
    int v1 , v2;
    for( int x , y ; m ; --m )
    {

        in >> v1 >> v2;

        x = First[v1];
        y = First[v2];


        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';



    }

}