Cod sursa(job #2170667)

Utilizator CozmaCatalinCozma Catalin CozmaCatalin Data 15 martie 2018 09:18:08
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.64 kb
#include <bits/stdc++.h>

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

using namespace std;

const int MAX = 100005;
vector <int > myVector[MAX];
int RMQmatrix[25][MAX<<1];
int Ap[MAX<<1];
int LG[MAX<<1];
int Level[MAX<<1];
int Questions;
int countt;
int N,M;
inline void scanDATA()
{
    in >> N >> Questions;
    for ( int i = 2 ; i <= N ; ++i)
    {
        int x;
        in >> x;
        myVector[x].push_back(i);
    }
}

void Euler(int node , int level)
{
    RMQmatrix[0][++countt] = node;
    Level[node] = level;
    Ap[node] = countt;
    for ( auto x : myVector[node])
        {
            Euler(x,level+1);
       RMQmatrix[0][++countt] = node;
        Level[node] = level;
        }
}

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)
    {
        int l = j+( 1 << ( i-1 ));
        if(Level[RMQmatrix[i-1][j]] < Level[RMQmatrix[i-1][l]])
            RMQmatrix[i][j] = RMQmatrix[i-1][j];
        else RMQmatrix[i][j] = RMQmatrix[i-1][l];
    }
}

inline 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][x];
    else return RMQmatrix[k][y-(1<<k)+1];
}
int main()
{
    scanDATA();
    Euler(1,0);
    RMQ();
    for ( int i = 1; i <= Questions ; ++i)
    {
        int x,y;
        in >> x >> y;
        int sol = LCA(x,y);
        out << sol <<"\n";
    }

}