Cod sursa(job #2115061)

Utilizator liviu2000Dragomirescu Liviu liviu2000 Data 26 ianuarie 2018 11:19:28
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.74 kb
#include <bits/stdc++.h>

using namespace std;

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

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

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)
{
    int i ;
    v.push_back(make_pair(nod,nivel)) ;
    if ( first[nod] == -1 )
        first[nod] = v.size()-1 ;
    for ( i = 0 ; i < graf[nod].size() ; i++ )
    {
        DFS(graf[nod][i],nivel+1) ;
        v.push_back(make_pair(nod,nivel)) ;
    }
}

int RMQ()
{
    int i , j , l ;
    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 ; i++ )
    {
        for ( j = 1 ; j <= nr-(1<<i)+1 ; j++ )
        {
            l = 1<<(i-1) ;
            rmq[i][j] = rmq[i-1][j+l] ;
            if ( v[rmq[i][j]].second > v[rmq[i-1][j]].second )
                rmq[i][j] = rmq[i-1][j] ;
        }
    }
}

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