Cod sursa(job #2833764)

Utilizator mihaipriboimihailucapriboi mihaipriboi Data 15 ianuarie 2022 17:25:46
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.98 kb
// Mihai Priboi

#include <stdio.h>
#include <algorithm>

// parsare
 
FILE *fin, *fout;
 
#define BUFFER 1 << 14
 
char buf[BUFFER];
int buf_index = BUFFER;
 
inline char read_char() {
  if( buf_index == BUFFER ) {
    fread( buf, 1, BUFFER, fin );
    buf_index = 0;
  }
  return buf[buf_index++];
}
 
inline int read_int() {
  char ch;
  int n;
  // citim non-cifrele
  ch = read_char();
  while( ch < '0' || ch > '9' )
    ch = read_char();
 
  n = 0;
  while( ch >= '0' && ch <= '9' ) {
    n = n * 10 + ch - '0';
    ch = read_char();
  }
 
  return n;
}
 
//

#define MAXN 100000
#define LOGN 16

int daddy[MAXN + 1][LOGN + 1];
int depth[MAXN + 1];

void getDepth( int nod ) {
  if( depth[nod] > 0 )
    return;
  
  getDepth(daddy[nod][0]);
  depth[nod] = depth[daddy[nod][0]] + 1;
}

int main() {
  int n, m, i, x, j, k, y, pas;
  fin = fopen( "lca.in", "r" );

  n = read_int();
  m = read_int();
  for( i = 2; i <= n; i++ )
    daddy[i][0] = read_int();
  
  for( i = 1; i <= LOGN; i++ )
    for( j = 1; j <= n; j++ )
      daddy[j][i] = daddy[daddy[j][i - 1]][i - 1];

  // calculam adancimea
  depth[1] = 1;
  for( i = 2; i <= n; i++ )
    getDepth(i);

  fout = fopen( "lca.out", "w" );

  for( k = 0; k < m; k++ ) {
    x = read_int();
    y = read_int();
    if( depth[x] < depth[y] )
      std::swap(x, y);

    // aducem la acelasi nivel
    pas = LOGN;
    while( pas >= 0 && depth[x] != depth[y] ) {
      if( daddy[x][pas] > 0 && depth[daddy[x][pas]] >= depth[y] )
        x = daddy[x][pas];
      pas--;
    }

    if( x != y ) {
      // cautam binar lca-ul
      pas = LOGN;
      while( pas >= 0 ) {
        if( daddy[x][pas] > 0 && daddy[y][pas] > 0 && daddy[x][pas] != daddy[y][pas] ) {
          x = daddy[x][pas];
          y = daddy[y][pas];
        }
        pas--;
      }
      x = daddy[x][0];
    }

    fprintf( fout, "%d\n", x );
  }

  fclose( fin );
  fclose( fout );
  return 0;
}