Cod sursa(job #2917316)

Utilizator mircea_007Mircea Rebengiuc mircea_007 Data 4 august 2022 13:16:04
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.44 kb
// This program was written by Mircea Rebengiuc
// on 04.08.2022
// for problem lca

#include <stdio.h>
#include <ctype.h>

FILE *fin, *fout;

static inline int fgetint(){
  int n = 0, ch;

  while( !isdigit( ch = fgetc( fin ) ) );
  do
    n = n * 10 + ch - '0';
  while( isdigit( ch = fgetc( fin ) ) );

  return n;
}

#define MAXN 100000
#define MAXL 17

int par[MAXN][1 + MAXL];
int depth[MAXN];
int L;

int getdepth( int u ){
  if( depth[u] ) return depth[u];

  return depth[u] = 1 + getdepth( par[u][0] );
}

int lca( int u, int v ){
  int delta, i;

  if( depth[u] > depth[v] )
    return lca( v, u );

  delta = depth[v] - depth[u];
  for( i = 0 ; i < L ; i++ )
    if( (delta & (1 << i)) )
      v = par[v][i];

  if( u == v )
    return u;

  for( i = L ; i-- ; )
    if( par[u][i] != par[v][i] ){
      u = par[u][i];
      v = par[v][i];
    }

  return par[u][0];
}

int main(){
  fin = fopen( "lca.in", "r" );
  fout = fopen( "lca.out", "w" );

  int n, i, l, q, a, b;
  
  n = fgetint();
  q = fgetint();
  par[0][0] = 0;
  for( i = 1 ; i < n ; i++ )
    par[i][0] = fgetint() - 1;

  depth[0] = 1;
  for( i = 1 ; i < n ; i++ ) getdepth( i );

  L = 0;
  while( (1 << L) <= n )
    L++;

  for( l = 1 ; l < L ; l++ )
    for( i = 0 ; i < n ; i++ )
      par[i][l] = par[par[i][l - 1]][l - 1];

  for( ; q-- ; ){
    a = fgetint() - 1;
    b = fgetint() - 1;

    fprintf( fout, "%d\n", 1 + lca( a, b ) );
  }

  fclose( fin );
  fclose( fout );

  return 0;
}