Cod sursa(job #3341578)

Utilizator DariusJohnDarius Dumitrescu DariusJohn Data 20 februarie 2026 09:50:58
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.24 kb
#include <bits/stdc++.h>
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
vector<vector<int>> adj;
vector<vector<int>> up;
vector<int> depth;
const int LOG = 20;

// binary lifting
void dfs(int node, int parent) {
  up[node][0] = parent;

  for (int i = 1; i < LOG; i++) {
    up[node][i] = up[up[node][i - 1]][i - 1];
  }

  for (auto it : adj[node]) {
    if (it != parent) {
      depth[it] = depth[node] + 1;
      dfs(it, node);
    }
  }
}

int ka(int node, int k) {
  for (int i = 0; i < LOG; i++) {
    if (k & (1 << i))
      node = up[node][i];
  }
  return node;
}

int lca(int a, int b) {
  if (depth[a] < depth[b])
    swap(a, b);

  int diff = depth[a] - depth[b];

  a = ka(a, diff);

  if (a == b)
    return a;

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

int main() {
  int N, Q;
  fin >> N >> Q;
  depth.resize(N + 1, 0);
  adj.resize(N + 1);
  up.resize(N + 1, vector<int>(LOG));
  for (int i = 2; i <= N; i++) {
    int x;
    fin >> x;
    adj[x].push_back(i);
  }
  dfs(1, 1);
  for (int i = 0; i < Q; i++) {
    int L, R;
    fin >> L >> R;
    fout << lca(L, R) << "\n";
  }
  return 0;
}