Cod sursa(job #3205981)

Utilizator v_mateiVatamanu Matei v_matei Data 21 februarie 2024 11:54:50
Problema Lowest Common Ancestor Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.03 kb
#include <fstream>
#include <iostream>
#include <vector>

#define NMAX 100'000
#define LOG 20

std::ofstream cout("lca.out");
std::ifstream cin("lca.in");
int n, m;
std::vector<int> G[NMAX];
int up[NMAX][40], tin[NMAX], tout[NMAX], timp = 0;

void citire() {
  cin >> n >> m;
  int a;
  for (int i = 1; i < n; i++) {
    cin >> a;
    G[a].push_back(i + 1);
  }
}

void dfs(int nod, int tata) {
  tin[nod] = ++timp;

  up[nod][0] = tata;
  for (int j = 1; j <= LOG; j++) {
    up[nod][j] = up[up[nod][j - 1]][j - 1];
  }

  for (auto it : G[nod]) {
    if (it != tata)
      dfs(it, nod);
  }
  tout[nod] = ++timp;
}

bool is_anc(int a, int b) { return tin[a] <= tin[b] && tout[a] >= tout[b]; }

int lca(int a, int b) {
  if (is_anc(a, b))
    return a;
  if (is_anc(b, a))
    return b;
  for (int i = LOG; i >= 0; i--) {
    if (!is_anc(up[a][i], b))
      a = up[a][i];
  }
  return up[a][0];
}

int main() {
  citire();
  dfs(1, 1);
  int u, v;
  for (int i = 1; i <= m; i++) {
    cin >> u >> v;
    cout << lca(u, v) << '\n';
  }
  return 0;
}