Cod sursa(job #2834816)

Utilizator Luca_Miscocilucainfoarena Luca_Miscoci Data 17 ianuarie 2022 18:27:20
Problema Lowest Common Ancestor Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.59 kb
#include <fstream>
#include <algorithm>
#define NMAX 1000000
#define LOG 16
using namespace std;

int depth[NMAX + 1];
int father[NMAX + 1][LOG + 1];

inline int log (int x){
  int log;

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

  return log;
}

inline int calcdepth (int node){
  if (node == 1)
    return 0; // root
  if ( !depth[node] )
    depth[node] = calcdepth(father[node][0]) + 1;

  return depth[node];
}

int lca (int node1, int node2){
  if (depth[node1] > depth[node2]){
    int aux;
    aux = node1;
    node1 = node2;
    node2 = aux;
  }

  int logg = log (depth[node2] - depth[node1]);
  if (depth[node1] < depth[node2]){
     while (logg >= 0 && depth[node2] > depth[node1]){
        node2 = father[node2][logg];
        logg--;
     }
  }

  if (node1 != node2){
    for (logg = log(depth[node1]); logg >= 0; logg--){
      if (father[node1][logg] && father[node1][logg] != father[node2][logg])
        node1 = father[node1][logg], node2 = father[node2][logg];
    }
    node1 = node2 = father[node1][0];
  }
  return node1;
}
int main(){

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

  int n, m, a, b;

  fin >> n >> m;
  for (int i = 2; i <= n; i ++)
    fin >> father[i][0];

  for (int i = 2; i <= n; i++)
    depth[i] = calcdepth(i);

  for (int j = 1; (1 << j) < n; j++)
    for (int i = 2; i <= n; i++)
      father[i][j] = father[father[i][j - 1]][j - 1];

  while (m--){
    fin >> a >> b;
    if (lca(a, b) == 0)
      fout << "1";
    else
      fout << lca(a, b) << "\n" ;
  }
  return 0;
}