Cod sursa(job #1042879)

Utilizator Dddarius95Darius-Florentin Neatu Dddarius95 Data 27 noiembrie 2013 19:25:28
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.95 kb
#include <vector>
#include <fstream>
#define Nmax 100099
#define Lmax 20
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");

int K,N,M,L[2*Nmax],Euler[2*Nmax],Lg[2*Nmax],First[Nmax],RMQ[Lmax][2*Nmax];
vector < int > Arb[Nmax];

inline void ReadInput()
{
    f>>N>>M;
    for(int i=2;i<=N;++i)
    {
        int x;
        f>>x;
        Arb[x].push_back(i);
    }
}

void DFS(int nod, int level)
{
    Euler[++K]=nod; //nodul actual este adaugat in reprezentarea Euler a arborelui
    L[K]=level; //se retine nivelul fiecarei pozitii din reprezentarea Euler a arborelui
    First[nod]=K; //se retine si prima aparitie a fiecarui nod in reprezentarea Euler a arborelui

    vector < int > :: iterator it;
    for(it=Arb[nod].begin();it!=Arb[nod].end();++it)
    {
        DFS(*it,level+1);
        Euler[++K]=nod;
        L[K]=level;
    }
}

void Make_RMQ()
{
    //in Rmq[i][j] va fi nodul de nivel minim
    //dintre pozitiile (j, j + 2^i - 1) din reprezentarea Euler a arborelui
    for(int i=2;i<=K;++i)Lg[i]=Lg[i>>1]+1;
    for(int j=1;j<=K;++j)RMQ[0][j]=j;
    for(int i=1;(1<<i)<K;++i)
      for(int j=1 ; j<=K-(1<<i) ; ++j)
        {
            int l=( 1<<(i-1) );
            RMQ[i][j] = RMQ[i-1][j];
            if( L[ RMQ[i-1][j+l] ] < L[ RMQ[i][j] ]) RMQ[i][j]=RMQ[i-1][j + l];
        }
}

int LCA(int x, int y)
{
    //LCA-ul nodurilor x si y va fi nodul
    //cu nivel minim din secventa (First[x], First[y]) din reprezentarea Euler a arborelui
    int diff,l,sol,sh,a=First[x],b=First[y];
    if(a>b)swap(a,b);
    diff=b-a+1;
    l=Lg[diff];
    sol=RMQ[l][a];
    sh=diff-(1<<l);
    if(L[ sol ] > L[ RMQ[l][a + sh] ])sol=RMQ[l][a+sh];
    return Euler[sol];
}


int main()
{
    ReadInput();
    DFS(1,0); // Arbore cu radacina in 1 (radacina are nivel 0)
    Make_RMQ();
    for(int i=1;i<=M;++i)
    {
        int x,y;
        f>>x>>y;
        g<<LCA(x,y)<<'\n';
    }
    return 0;
}