Cod sursa(job #3283596)

Utilizator mircea_007Mircea Rebengiuc mircea_007 Data 9 martie 2025 22:31:28
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.25 kb
#include <stdio.h>
#include <vector>

const int MAXN = 1e5;
std::vector<int> adj[MAXN];
int dep[MAXN];
int par[MAXN];
int jump[MAXN];

void dfs( int u, int p ) {
  for( int v : adj[u] )
    if( v != p ){
      par[v] = u;
      dep[v] = 1 + dep[u];

      if( dep[u] - dep[jump[u]] == dep[jump[u]] - dep[jump[jump[u]]] )
        jump[v] = jump[jump[u]];
      else
        jump[v] = u;

      dfs( v, u );
    }
}

int lca( int a, int b ) {
  if( dep[a] < dep[b] )
    std::swap( a, b );

  while( dep[a] > dep[b] )
    if( dep[jump[a]] >= dep[b] )
      a = jump[a];
    else
      a = par[a];

  while( a != b )
    if( jump[a] != jump[b] ){
      a = jump[a];
      b = jump[b];
    }else{
      a = par[a];
      b = par[b];
    }

  return a;
}

int main() {
  FILE *fin = fopen( "lca.in", "r" );
  FILE *fout = fopen( "lca.out", "w" );
  
  int n, q;
  fscanf( fin, "%d%d", &n, &q );

  for( int i = 1; i < n; i++ ){
    int par;
    fscanf( fin, "%d", &par );
    par--;

    adj[par].push_back( i );
    adj[i].push_back( par );
  }

  dep[0] = par[0] = jump[0] = 0;
  dfs( 0, 0 );

  for( int i = 0; i < q; i++ ){
    int a, b;
    fscanf( fin, "%d%d", &a, &b );
    fprintf( fout, "%d\n", 1 + lca( --a, --b ) );
  }

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