Cod sursa(job #2835742)

Utilizator iraresmihaiiordache rares mihai iraresmihai Data 19 ianuarie 2022 10:30:16
Problema Lowest Common Ancestor Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.69 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;

  if ( level[a] > level[b] )
    swap(a, b);

  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);

  if ( a != b ) {
    for ( i = lg[level[a]]; i >= 0; --i ) {
      if ( parents[a][i] && parents[a][i] != parents[b][i] )
        a = parents[a][i], b = parents[b][i];
    }

    a = parents[a][0];
  }

  return a;
}

void buildDepht(int pos) {
  if ( pos == 1 ) {
    return;
  }

  if ( level[pos] == 0 ) {
    buildDepht(parents[pos][0]);
    level[pos] = level[parents[pos][0]] + 1;
  }
}

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++ )
    buildDepht(i);

  for ( i2 = 1; i2 <= lg[level[n]]; i2++ ) {
    for ( i = 2; i <= n; i++ ) {
      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;
}