Cod sursa(job #761525)

Utilizator matei_cChristescu Matei matei_c Data 26 iunie 2012 13:11:37
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.59 kb
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;

#define maxn 200010
#define maxlog 20

int n,t,indice ;
int euler[maxn],m[maxn][maxlog],first[maxn],lvl[maxn] ;
vector <int> vecini[maxn] ;

void df(int nod,int level)
{
	
    euler[++indice] = nod ;
    lvl[indice] = level ;
    first[nod] = indice ;
    
	for(size_t i=0;i<vecini[nod].size();++i)
    {
        df ( vecini[nod][i] , level + 1 ) ;
        euler[++indice] = nod ;
        lvl[indice] = level ;
	}
}


void rmq()
{
	for(int i=0;i<indice;++i)
		m[i][0] = i ;
	
	for(int j=1;(1 << j) <= indice;++j)
    {
        for(int i=0;i + (1 << j) - 1 < indice;++i)
        {
            if( lvl[ m[i][j-1] ] < lvl[ m[i + (1 << (j - 1)) ][j - 1] ] )
                m[i][j] = m[i][j-1] ;
			else
                m[i][j] = m[i + (1 << (j - 1)) ][j-1] ;
		}
	}
	
}


int LCA(int x,int y)
{
    int a,b,log ;
    
	a = first[x] ;
    b = first[y] ;
    
	if( a > b )
		swap ( a , b ) ;
    
	log = (int) log2(b - a + 1) ;
	
    if( lvl[ m[a][log] ] <= lvl[ m[ b - (1 << log) + 1 ][log] ] )
		return euler[ m[a][log] ] ;
    else
		return euler[ m[ b - (1 << log) + 1][log] ] ;

}

int main()
{
	
    freopen("lca.in", "r", stdin);
    freopen("lca.out", "w", stdout);
    
    scanf("%d%d",&n,&t);
	
    indice = -1;
    for(int i=2;i<=n;++i) 
    {
		int x ;
        scanf("%d",&x);
        vecini[x].push_back(i) ;
    }
	
    df ( 1 , 0 ) ;
    
	++ indice ;
    
	rmq() ;
    
	for(int i=0;i<t;++i)
    {
		int x,y ;
        scanf("%d%d",&x,&y);
        printf("%d\n",LCA( x , y ) );
    }
	
    return 0;

}