Cod sursa(job #3156152)

Utilizator AlexandruBenescuAlexandru Benescu AlexandruBenescu Data 10 octombrie 2023 18:04:32
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.25 kb
#include <bits/stdc++.h>
#define L 100005
#define BIT_MAX 16
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");

int n, q;
int v[L], t[BIT_MAX + 1][L], lev[L];

void build_t() {
  t[0][1] = lev[1] = 1;
  for (int i = 2; i <= n; i++)
    t[0][i] = v[i];

  for (int bit = 1; bit <= BIT_MAX; bit++)
    for (int i = 1; i <= n; i++)
      t[bit][i] = t[bit - 1][t[bit - 1][i]];
}

int get_lev(int node) {
  if (lev[node])
    return lev[node];
  lev[node] = get_lev(t[0][node]) + 1;
  return lev[node];
}

int get_kth_parent(int node, int k) {
  int ans = node;
  for (int bit = 0; bit <= BIT_MAX; bit++)
    if ((1 << bit) & k)
      ans = t[bit][ans];
  return ans;
}

int LCA(int x, int y) {
  int lev_x = get_lev(x);
  int lev_y = get_lev(y);
  if (lev_x > lev_y)
    x = get_kth_parent(x, lev_x - lev_y);

  if (x == y)
    return x;

  for (int bit = BIT_MAX; bit >= 0; bit--)
    if (t[bit][x] != t[bit][y]) {
      x = t[bit][x];
      y = t[bit][y];
    }
  return t[0][x];
}

int main() {
  fin >> n >> q;
  for (int i = 2; i <= n; i++)
    fin >> v[i];

  build_t();

  for (int i = 1; i <= q; i++) {
    int x, y;
    fin >> x >> y;
    fout << LCA(x, y) << "\n";
  }
  return 0;
}