Cod sursa(job #2900100)

Utilizator AlexandruBenescuAlexandru Benescu AlexandruBenescu Data 10 mai 2022 10:44:40
Problema Lowest Common Ancestor Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.23 kb
#include <bits/stdc++.h>
#define L 100005
#define S 20
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
vector <int> g[L];
int v[L + L], vp[L], rmq[S][L + L], lg[L], lev[L], pos, lv;
void DFS(int node, int prev_node){
  v[pos++] = node;
  lev[node] = lv++;
  for (auto it : g[node])
    DFS(it, node);
  v[pos++] = prev_node;
  lv--;
}
inline int minlev(int a, int b){
  if (lev[a] < lev[b])
    return a;
  return b;
}
int main(){
  int n, q, i, j, root, x, y, p;
  fin >> n >> q;
  root = 1;
  for (i = 2; i <= n; i++){
    fin >> x;
    g[x].push_back(i);
  }
  pos = lv = 1;
  DFS(root, 0);
  for (i = 1; i < n + n; i++)
    vp[v[i]] = i;
  for (i = 1; i <= n + n - 1; i++)
    rmq[0][i] = v[i];
  p = 0;
  for (i = 1; i <= n + n - 1; i++){
    if ((1 << (p + 1)) == i)
      p++;
    lg[i] = p;
  }
  for (i = 1; (1 << i) <= n + n - 1; i++)
    for (j = 1; j <= n + n - (1 << i); j++)
      rmq[i][j] = minlev(rmq[i - 1][j], rmq[i - 1][j + (1 << (i - 1))]);
  for (i = 0; i < q; i++){
    fin >> x >> y;
    x = vp[x];
    y = vp[y];
    if (x > y)
      swap(x, y);
    p = lg[y - x + 1];
    fout << minlev(rmq[p][x], rmq[p][y - (1 << p) + 1]) << "\n";
  }
  return 0;
}