Cod sursa(job #2134359)

Utilizator CozmaCatalinCozma Catalin CozmaCatalin Data 17 februarie 2018 21:16:50
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.84 kb
#include <bits/stdc++.h>

using namespace std;

const int MAX = 100005;

int Level[MAX << 1];
int Ap[MAX];
int RMQmatrix[10 << 1][MAX << 1];
int Lg[MAX << 1];

int countt;

vector < int > myVector[MAX];

int N,M;

void Read()
{
    for ( int i = 2 ; i <= N ; ++i)
    {
        int x;
        scanf("%d" , &x);
        myVector[x].push_back(i);
    }
}

void EULERdfs(int currentNode , int currentLevel)
{
    RMQmatrix[0][++countt] = currentNode;
    Level[currentNode] = currentLevel;
    Ap[currentNode] = countt;

    for ( size_t k = 0 ; k < myVector[currentNode].size() ; ++k)
    {
        int Neighbor = myVector[currentNode][k];

        EULERdfs(Neighbor , currentLevel+1);

        RMQmatrix[0][++countt] = currentNode;
        Level[currentNode] = currentLevel;
    }
}

void RMQ()
{
    Lg[1] = 0;

    for ( int i = 2 ; i <= countt ; ++i)
        Lg[i] = Lg[i/2] +1;


    for ( int i = 1; i <= Lg[countt] ; ++i)
        for ( int j = 1 ; j <= countt - ( 1 << (i-1) ) ; ++j)
    {
        if(Level[RMQmatrix[i-1][j]] < Level[RMQmatrix[i-1][j+(1<<(i-1))]])
            RMQmatrix[i][j] = RMQmatrix[i-1][j];
        else RMQmatrix[i][j] = RMQmatrix[i-1][j+(1<<(i-1))];
    }


}

int LCA( int a , int b)
{
    int x = Ap[a];
    int y = Ap[b];

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

    int k = Lg[y-x+1];

    if(Level[RMQmatrix[k][x]] > Level[RMQmatrix[k][y - ( 1 << k) +1]])
        return RMQmatrix[k][y - ( 1 << k) +1];

    else return RMQmatrix[k][x];
}

int main()
{
    freopen("lca.in" , "r" , stdin);
    freopen("lca.out" , "w" , stdout);

    scanf("%d%d" , &N,&M);

    Read();
    EULERdfs(1,0);
   RMQ();

    for ( int i = 1; i <= M ; ++i)
    {
        int x,y;

        scanf("%d%d" , &x , &y );

       printf("%d\n" , LCA(x,y));

    }




    return 0;
}