Cod sursa(job #3251973)

Utilizator AlexandruBenescuAlexandru Benescu AlexandruBenescu Data 27 octombrie 2024 22:10:16
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.46 kb
#include <bits/stdc++.h>
#define L 100005
#define S 17
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");

int n, q;
vector <int> G[L];
bool vis[L];
int t[S][L], lev[L];

void buildFathers(int node) {
  vis[node] = true;
  for (auto it : G[node])
    if (!vis[it]) {
      t[0][it] = node;
      lev[it] = lev[node] + 1;
      buildFathers(it);
    }
}

void buildT() {
  for (int i = 1; i <= n; i++) {
    vis[i] = false;
    lev[i] = 0;
  }
  for (int i = 0; i < S; i++)
    t[i][1] = 1;
  lev[1] = 1;
  buildFathers(1);
  for (int bit = 1; bit < S; bit++)
    for (int i = 1; i <= n; i++)
      t[bit][i] = t[bit - 1][t[bit - 1][i]];
}

int getKthparent(int x, int k) {
  for (int bit = S - 1; bit >= 0; bit--) {
    if (k >= (1 << bit)) {
      x = t[bit][x];
      k -= (1 << bit);
    }
  }
  return x;
}

int lca(int x, int y) {
  if (lev[x] > lev[y])
    x = getKthparent(x, lev[x] - lev[y]);
  else
    y = getKthparent(y, lev[y] - lev[x]);
  if (x == y)
    return x;
  for (int bit = S - 1; 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++) {
    int x;
    fin >> x;
    G[i].push_back(x);
    G[x].push_back(i);
  }

  buildT();

  for (int i = 1; i <= q; i++) {
    int a, b;
    fin >> a >> b;
    fout << lca(a, b) << "\n";
  }
  return 0;
}