Cod sursa(job #2834268)

Utilizator vladburacBurac Vlad vladburac Data 16 ianuarie 2022 18:43:27
Problema Lowest Common Ancestor Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.48 kb
#include <iostream>
#include <vector>
using namespace std;
#define NMAX 100000
#define MAXLOG 18

vector <int> children[NMAX+1];
int rmq[2*NMAX][MAXLOG+1];
int euler[2*NMAX-1], level[NMAX+1], first_occ[NMAX+1];
int logg[2*NMAX];
int nr = 0;

void dfs( int a, int lvl ) {
  euler[nr] = a;
  first_occ[a] = nr;
  level[a] = lvl;
  nr++;
  for( auto i: children[a] ) {
    dfs( i, lvl + 1 );
    euler[nr++] = a;
  }
}

static inline int f( int a, int b ) {
  if( level[a] < level[b] )
    return a;
  return b;
}

int main() {
  FILE *fin, *fout;
  int n, m, a, b, i, j, x, y, len;
  fin = fopen( "lca.in", "r" );
  fout = fopen( "lca.out", "w" );
  fscanf( fin, "%d%d", &n, &m );
  for( i = 1; i < n; i++ ) {
    fscanf( fin, "%d", &a );
    children[a].push_back( i + 1 );
  }
  dfs( 1, 1 );
  /*for( i = 0; i < nr; i++ )
    printf( "%d\n", euler[i] );*/
  logg[1] = 0;
  for( i = 2; i <= n; i++ )
    logg[i] = logg[i/2] + 1;

  for( j = 0; j < nr; j++ )
    rmq[j][0] = euler[j];
  for( i = 1; ( 1 << i ) <= nr; i++ ) {
    for( j = 0; j < nr - ( 1 << i ) + 1; j++ )
      rmq[j][i] = f( rmq[j][i-1], rmq[j+(1<<(i-1))][i-1] );
  }
  for( i = 0; i < m; i++ ) {
    fscanf( fin, "%d%d", &a, &b );
    x = first_occ[a];
    y = first_occ[b];
    if( x > y )
      swap( x, y );
    len = y - x + 1;
    fprintf( fout, "%d\n", f( rmq[x][logg[len]], rmq[y - ( 1 << logg[len] ) + 1][logg[len]] ) );
  }
  fclose( fin );
  fclose( fout );
  return 0;
}