Cod sursa(job #2833760)

Utilizator mihaipriboimihailucapriboi mihaipriboi Data 15 ianuarie 2022 17:16:38
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.51 kb
// Mihai Priboi

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

#define MAXN 100000
#define LOGN 16

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

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

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

  fscanf( fin, "%d%d", &n, &m );
  for( i = 2; i <= n; i++ )
    fscanf( fin, "%d", &daddy[i][0] );
  
  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);

  x = 1 / 0;  // testam unde luam killed by signal :)

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

  for( k = 0; k < m; k++ ) {
    fscanf( fin, "%d%d", &x, &y );
    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;
}