Cod sursa(job #2834493)

Utilizator iraresmihaiiordache rares mihai iraresmihai Data 17 ianuarie 2022 09:45:41
Problema Lowest Common Ancestor Scor 90
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.54 kb
#include <stdio.h>
#include <algorithm>

using namespace std;

#define MAXN 100000

int parents[MAXN + 1][17];
int level[MAXN + 1];
int lg[MAXN + 1];

void precalcLog(int n) {
  int i;

  for ( i = 2; i <= n; i++)
    lg[i] = lg[i / 2] + 1;
}

int calcLevel(int pos) {
  int result;

  result = 0;
  while ( pos > 1 )
    result++, pos = parents[pos][0];

  return result;
}

void bringToSameLevel(int& a, int& b) {
  int nr, ok = false;

  if ( level[a] > level[b] )
    swap(a, b);
    if ( a + b == 21 )
      ok = true;

  while ( level[a] < level[b] ) {
    nr = lg[level[b] - level[a]];
    b = parents[b][nr];
  }
}

int lca(int a, int b) {
  int i;

  bringToSameLevel(a, b);

  while ( a != b ) {
    i = 0;
    do
      i++;
    while ( i <= lg[level[a]] && parents[a][i] != parents[b][i] );
    i--;

    a = parents[a][i];
    b = parents[b][i];
  }

  return a;
}

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

  int n, m, i, i2, a, b;

  fscanf(fin, "%d%d", &n, &m);

  precalcLog(n);

  for ( i = 2; i <= n; i++ ) {
    fscanf(fin, "%d", &parents[i][0]);
  }

  for ( i = 2; i <= n; i++ )
    level[i] = calcLevel(i);

  for ( i = 2; i <= n; i++ ) {
    for ( i2 = 1; i2 <= lg[level[i]]; i2++ ) {
      parents[i][i2] = parents[parents[i][i2 - 1]][i2 - 1];
    }
  }

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

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