Cod sursa(job #2840304)

Utilizator Antonia_onisoruantonia onisoru Antonia_onisoru Data 27 ianuarie 2022 12:58:10
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.52 kb
#include <iostream>
#include <fstream>

using namespace std;

ifstream in("lca.in");
ofstream out("lca.out");

const int MAXN = 100000;
const int MAX_POW = 16;

int nivel[MAXN + 1];
int table[MAXN + 1][MAX_POW + 1];

int log(int x){
  int log;

  log = 0;
  while(x > 1){
    log++;
    x>>=1;
  }

  return log;
}

int computeNivel(int node){
  if( node == 1 )
    return 0;

  if(!nivel[node]){
    nivel[node] = computeNivel(table[node][0]) + 1;
  }

  return nivel[node];
}

int lca( int a, int b ){
  if( nivel[b] < nivel[a] )
    swap(a, b);

  int j;
  if( nivel[b] > nivel[a] ){
    j = log(nivel[b] - nivel[a]);
    while( j >= 0 &&  nivel[b] > nivel[a] ){
      if( nivel[b] - ( 1 << j ) >= nivel[a] )
        b = table[b][j];
      j--;
    }
  }

  if( a != b ){
    for( j = log(nivel[a]); j >= 0; j-- ){
      if( table[a][j] != table[b][j] && table[a][j] != 0 ){
        a = table[a][j];
        b = table[b][j];
      }
    }
    a = table[a][0];
  }

  return a;
}

int main()
{
    int n, m, i, f;
    in>>n>>m;

    for( i = 2; i <= n; i++ ){
      in>>f;
      table[i][0] = f;
    }
    for( i = 2; i <= n; i++ ){
      nivel[i] = computeNivel(i);
      //out<<"nivel: "<<nivel[i]<<'\n';
    }

    for( int j = 1; (1 << j) < n; j++ ){
      for( i = 1; i <= n; i++ ){
        table[i][j] = table[table[i][j - 1]][j - 1];
      }
    }

    int a, b;
    for( i = 0; i < m; i++ ){
      in>>a>>b;
      out<<lca(a, b)<<'\n';
    }
    return 0;
}