Cod sursa(job #1231563)

Utilizator lucian666Vasilut Lucian lucian666 Data 20 septembrie 2014 22:57:39
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.1 kb



#include <fstream>
#include <algorithm>
#include <vector>

#define NN 100005
#define INF 0x3f3f3f3f
#define pb push_back

using namespace std;

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

int n , m ;
int K;

int Lev[ NN * 2 ] , Eul[ NN * 2] , First[ NN ] ;
int arb[ NN << 4];

int lsol , sol , st , dr;

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

void Read();
void Dfs( int start , int level );
void build( int nod , int li , int lf );
void query( int nod , int li , int lf );
int lca( int x , int y );

int main()
{

    Read();
    Dfs(1,0);
    build(1,1,K);

    for( ; m ; --m )
    {

        int x , y;

        in >> x >> y;
        out << lca( x , y ) << '\n';

    }

    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 )
{

    Eul[ ++K ] = nod;
    Lev[ K ] = level;
    First[ nod ] = K;

    for( IT i = G[nod].begin(); i!=G[nod].end(); ++i)
    {
        Dfs( *i , level + 1 );
        Eul[ ++K ] = nod;
        Lev[ K ] = level;
    }

}

void build( int nod , int li , int lf )
{

    if( li == lf )
    {

        arb[nod] = li;
        return;
    }

    int mid = ( li + lf ) >> 1;
    build( ( nod << 1 ) , li , mid );
    build( ( nod << 1 ) + 1 , mid + 1 ,lf );


    if( Lev[arb[ (nod<<1) ]] <= Lev[arb[ (nod<<1)+1]] )
        arb[nod] = arb[(nod<<1)];
    else
        arb[nod] = arb[(nod<<1)+1];

}

void query( int nod , int li , int lf )
{

    if( st <=li && lf <= dr)
    {

        if( Lev[arb[nod]] < lsol  )
         sol = Eul[arb[nod]] , lsol = Lev[arb[nod]];
        return;
    }

    int mid = ( li + lf ) >> 1;

    if( st <= mid )
        query( ( nod << 1 ) , li , mid );

    if( mid < dr )
        query( ( nod << 1 ) + 1 , mid + 1 , lf );

}

int lca( int x , int y )
{

    st = First[x];
    dr = First[y];

    if( st > dr )
        swap(st,dr);


    sol = lsol = INF;

    query(1,1,K);

    return sol;

}