Cod sursa(job #1354719)

Utilizator superman_01Avramescu Cristian superman_01 Data 21 februarie 2015 23:17:39
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.68 kb
#include <fstream>
#include <algorithm>
#include <vector>
#include <cstring>

#define NMAX 100005
#define get_max(a,b) ((a)>(b)?(a):(b))
#define get_min(a,b) ((a)<(b)?(a):(b))

using namespace std;

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

vector < int > G[NMAX] ;
int N , M , TT[NMAX] ;
int euler[ 2*NMAX] , Lvl[2*NMAX] , first[NMAX];
int K , Log[NMAX] , RMQ[20][NMAX];
bool used[NMAX];
void DFS ( int node , int level );
void PreBuild( void );
void Positive ( int &x ){
  (x<0?x=-x:x=x);
}
int main ( void ){
    int i , j , x , y;
    in >> N >> M ;
    for ( i = 1 ; i <= N ; ++i ) {
       in >> x;
       G[x].push_back ( i );
    }
    DFS ( 1 , 0 );
    PreBuild();
    for ( i = 1 ; i <= M ; ++i ){
      in >> x >> y;
      int a = first[x] , b = first[y];
      if ( a > b ) swap(a,b);
      int dif = b-a+1;
      int lg = Log[dif];
      if ( Lvl[RMQ[lg][a]] < Lvl[RMQ[lg][dif]] )
      out << euler[RMQ[lg][a]] ;
      else out << euler[RMQ[lg][dif]];
    }
    return 0 ;
}
void PreBuild( void ){
    int i , j ;
    for ( i = 2 ; i <= K ; ++i )
       Log[i] = Log[i/2] + 1 ;
    for ( i = 1 ; i <= K ; ++i )
       RMQ[0][i] = i;
    for ( i = 1 ; (1 << i ) < K ; ++i )
        for ( j = 1 ; j <= K - (1<<i) + 1 ; ++j )
        ( Lvl[RMQ[i-1][j]] < Lvl[RMQ[i-1][j+(1<<(i-1))]] ? RMQ[i][j] = RMQ[i-1][j]  : RMQ[i][j] = RMQ[i-1][ j + 1<<(i-1)] ) ;
}

void DFS ( int node , int level ){
     euler[++K] = node;
     Lvl [ K ]  = level;
     used[node]  = true;
     first[node] = K ;
    for ( vector < int > ::iterator it = G[node].begin() ; it != G[node].end() ; ++it )
    if ( !used[NMAX]){
        DFS ( *it , level + 1 );
        euler[++K] = node;
        Lvl[ K ] = level;
    }

}