Cod sursa(job #1804693)

Utilizator CodrutLemeniCodrut Lemeni CodrutLemeni Data 12 noiembrie 2016 21:28:27
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.91 kb
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#define N 100010
#define LGM 20

using namespace std;

vector<int> muc [N];
int parg [ N<<1 ], height [ N<<1 ], first [ N ] , lg[ N<<1 ] ;
int rmq[ N<<2 ][ LGM ];

int nod ;
void dfs(int k , int level){
    vector<int>::iterator it ;

    parg[nod] = k;
    height [ nod ] = level;
    first [ k ] = nod++ ;

    for( it = muc [ k ].begin() ; it != muc[ k ].end() ; it++ ){
        dfs( *it, level + 1);

        parg[ nod ] = k ;
        height[ nod++ ] = level ;
    }


}

void genrmq(){
    int i,j;

    for(i=2; i <= nod ;i++){
        lg[i]= lg[ i/2 ] + 1;
    }

    for( i = 1 ; i <= nod ; i++ ){
        rmq[i][0] = i ;
    }

    int pow2;
    for( j = 1 , pow2 = 1 ; pow2 * 2 <= nod ; j++ , pow2 <<= 1){
        for(i = 1 ; i + pow2 <= nod ; i++ ){
            rmq[ i ][ j ] =  rmq[ i ][ j-1 ];
            if( height[ rmq[ i+pow2 ][ j-1 ] ] < height[ rmq[ i ][ j-1 ] ]  ){
                rmq[ i ][ j ] = rmq[ i+pow2 ][ j-1 ];
            }
        }
    }

}

void swapn( int *x, int *y){

    int t;

    t=*x;
    *x=*y;
    *y=t;
}

int main(){
    int n,m,i;
    int x,y;
    int sol;

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

    scanf("%d%d",&n,&m);

    for(i=2;i<=n;i++){
        scanf("%d",&x);
        muc[x].push_back(i);
    }

    dfs(1,0);

    genrmq();

    for( i = 0 ; i < m ; i++ ){
        scanf("%d%d", &x , &y );
        x = first [x];
        y = first [y];

        if( y < x ){
            swapn( &x , &y);
        }
        int log =  lg[ y-x+1 ] ;
        if( height [ rmq[ x ][ log ] ] < height [ rmq[ y- ( 1<<log )+1 ][ log ] ]   ){
            sol = rmq[ x ][ log ] ;
        }else{
            sol = rmq[ y - ( 1<<log )+1 ][ log ];
        }
        printf("%d\n", parg[sol] );

    }


    return 0;
}