Cod sursa(job #2842286)

Utilizator iancupoppPopp Iancu Alexandru iancupopp Data 31 ianuarie 2022 15:18:11
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.31 kb
#include <fstream>
#include <vector>

using namespace std;

const int N = 1e5 + 5;
const int LOG = 18;
const int INF = (1 << 30);

vector<int> fii[N];
int niv[N], st[N], rmq[2 * N][LOG], lg[2 * N];
int p;

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

void calc_rmq(int poz, int val) {
  rmq[poz][0] = val;
  for (int i = 1; i <= lg[poz]; ++i) {
    int a = rmq[poz][i - 1];
    int b = rmq[poz - (1 << (i - 1))][i - 1];
    if (niv[a] < niv[b])
      rmq[poz][i] = a;
    else
      rmq[poz][i] = b;
  }
}

void dfs(int nod) {
  st[nod] = ++p;
  calc_rmq(p, nod);
  for (auto f: fii[nod]) {
    niv[f] = niv[nod] + 1;
    dfs(f);
    calc_rmq(++p, nod);
  }
}

int lca(int a, int b) {
  a = st[a], b = st[b];
  if (a > b)
    swap(a, b);
  int diff = b - a + 1 - (1 << lg[b - a + 1]);
  int min1 = rmq[b][lg[b - a + 1]];
  int min2 = rmq[b - diff][lg[b - a + 1]];
  if (niv[min1] < niv[min2])
    return min1;
  return min2;
}

int main() {
  ifstream cin("lca.in");
  ofstream cout("lca.out");
  int n, q;
  cin >> n >> q;
  for (int i = 2; i <= n; ++i) {
    int tata;
    cin >> tata;
    fii[tata].push_back(i);
  }
  precalc(2 * n);
  niv[0] = INF, niv[1] = 1;
  dfs(1);
  while (q--) {
    int a, b;
    cin >> a >> b;
    cout << lca(a, b) << "\n";
  }
  cin.close();
  cout.close();
  return 0;
}