Cod sursa(job #2914126)

Utilizator Alex_tz307Lorintz Alexandru Alex_tz307 Data 18 iulie 2022 20:50:00
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.49 kb
#include <bits/stdc++.h>

using namespace std;

ifstream fin("lca.in");
ofstream fout("lca.out");

const int kN = 1e5;
const int kM = 2e5;
const int kLog = 17;
int n, q, m, first[1 + kN], tour[1 + kM], dep[1 + kM], lg2[1 + kM], rmq[1 + kM][1 + kLog];
vector<int> g[1 + kN];

void dfs(const int &u, const int &level) {
  tour[++m] = u;
  dep[m] = level;
  first[u] = m;
  for (const int &v : g[u]) {
    dfs(v, level + 1);
    tour[++m] = u;
    dep[m] = level;
  }
}

static inline void computeRmq() {
  for (int i = 2; i <= m; ++i) {
    lg2[i] = lg2[i >> 1] + 1;
  }
  for (int i = 1; i <= m; ++i) {
    rmq[i][0] = i;
  }
  for (int l = 1; l <= lg2[m]; ++l) {
    for (int i = 1; i + (1 << l) - 1 <= m; ++i) {
      rmq[i][l] = rmq[i][l - 1];
      int other = rmq[i + (1 << (l - 1))][l - 1];
      if (dep[other] < dep[rmq[i][l]]) {
        rmq[i][l] = other;
      }
    }
  }
}

static inline int getLca(int x, int y) {
  x = first[x];
  y = first[y];
  if (y < x) {
    swap(x, y);
  }
  int l = lg2[y - x + 1];
  int left = rmq[x][l], right = rmq[y - (1 << l) + 1][l];
  if (dep[left] < dep[right]) {
    return tour[left];
  }
  return tour[right];
}

int main() {
  fin >> n >> q;
  for (int v = 2; v <= n; ++v) {
    int u;
    fin >> u;
    g[u].emplace_back(v);
  }
  dfs(1, 0);
  computeRmq();
  for (int i = 0; i < q; ++i) {
    int x, y;
    fin >> x >> y;
    fout << getLca(x, y) << '\n';
  }
  fin.close();
  fout.close();
  return 0;
}