Cod sursa(job #2112864)

Utilizator liviu2000Dragomirescu Liviu liviu2000 Data 23 ianuarie 2018 22:23:38
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.83 kb
#include <bits/stdc++.h>

using namespace std;

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

vector<int> graf[100001] ;
int rmq[20][200001];
int first[100001] ;
int lg[100001] ;
vector<pair<int,int> > vizit;
int n , m , nr ;

void citire()
{
    int x;
    fin >> n >> m ;
    first[1] = -1 ;
    for ( int i = 1 ; i <= n-1 ; i++ )
    {
        first[i+1] = -1 ;
        fin >> x ;
        graf[x].push_back(i+1) ;
    }
}

void DFS(int nod,int nivel)
{
    vizit.push_back(make_pair(nod,nivel)) ;
    if ( first[nod] == -1 )
        first[nod] = vizit.size()-1 ;
    for ( int i = 0 ; i < graf[nod].size() ; i++ )
    {
        DFS(graf[nod][i],nivel+1) ;
        vizit.push_back(make_pair(nod,nivel)) ;
    }
}

void RMQ()
{
    int i, j , l ;
    lg[1] = 0 ;
    for ( i = 2 ; i < nr ; i++ )
        lg[i] = lg[i/2]+1 ;
    for ( i = 1 ; i < nr ; i++ )
        rmq[0][i] = i;
    for ( i = 1 ; (1<<i) < nr-1 ; i++ )
    {
        for ( j = 1 ; j < nr-(1<<i)+1 ; j++ )
        {
            l=1<<(i-1) ;
            rmq[i][j] = rmq[i-1][j+l] ;
            if ( vizit[rmq[i-1][j]].second < vizit[rmq[i-1][j+l]].second )
                rmq[i][j] = rmq[i-1][j] ;
        }
    }
}

int main()
{
    citire() ;
    vizit.push_back(make_pair(0,0)) ;
    DFS(1,0) ;
    int minim , sol , j , x , y , dif , lo2 ;
    nr = vizit.size() ;
    RMQ() ;
    for ( int i = 1 ; i <= m ; i++ )
    {
        fin >> x >> y ;
        x = first[x] ;
        y = first[y] ;
        if ( x > y )
            swap(x,y) ;
        dif = y-x+1 ;
        lo2 = lg[dif] ;
        dif = dif-(1<<lo2) ;
        if ( vizit[rmq[lo2][x]].second < vizit[rmq[lo2][x+dif]].second )
            sol = rmq[lo2][x] ;
        else
            sol = rmq[lo2][x+dif] ;
        fout << vizit[sol].first << '\n' ;
    }
}