Cod sursa(job #1393821)

Utilizator danalex97Dan H Alexandru danalex97 Data 19 martie 2015 19:39:05
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.61 kb
#include <fstream>
#include <algorithm>
#include <vector>

using namespace std;

const int Nmax = 100011 ;
const int LgNx = 20 ;
const int Mmax = 2000011 ;

int N,M,L;

vector< int > V[Nmax];
int Rmq[LgNx][Nmax << 2];

int Lg[Nmax << 1];
int High[Nmax << 1];
int Lvl[Nmax << 1];
int First[Nmax];

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

void Get( int Nod , int Niv)
{
    High[ ++L ]=Nod;
    Lvl[ L ]=Niv;
    First[ Nod ]=L;

    for (int i=0;i<int( V[Nod].size() );++i)
    {
        Get( V[Nod][i] , Niv+1 );
        High[ ++L ]=Nod;
        Lvl[ L ]=Niv;
    }
}

void Build()
{
    for (int i=1;i<=L;++i)
        Lg[i]=Lg[i>>1]+1;
    for (int i=1;i<=L;++i)
        Rmq[0][i]=i;

    for (int i = 1; (1 << i) < L; ++i)
        for (int j = 1; j <= L - (1 << i); ++j)
        {
            int l = 1 << (i - 1);
            Rmq[i][j] = Rmq[i-1][j];
            if ( Lvl[Rmq[i-1][j + l]] < Lvl[Rmq[i][j]] )
                Rmq[i][j] = Rmq[i-1][j + l];
        }
}

int LCA(int x, int y)
{
    int Difrence, l, Sol, Sift;

    int a = First[x];
    int b = First[y];
    if (a > b) swap(a, b);

    Difrence = b - a + 1;
    l = Lg[ Difrence ]-1;

    Sol = Rmq[l][a];
    Sift = Difrence - (1 << l);

    if( Lvl[Sol] > Lvl[Rmq[l][a + Sift]] )
        Sol = Rmq[l][a + Sift];
    return High[Sol];
}

int main()
{
    F>>N>>M;
    for (int i=2;i<=N;++i)
    {
        int x;
        F>>x;
        V[x].push_back( i );
    }

    Get( 1,0 );
    Build();

    while ( M-- )
    {
        int x,y;
        F>>x>>y;
        G<<LCA( x,y )<<'\n';
    }
}