Cod sursa(job #3214905)

Utilizator Traian_7109Traian Mihai Danciu Traian_7109 Data 14 martie 2024 15:48:38
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.36 kb
#include <bits/stdc++.h>

using namespace std;

const int nmax = 1e5;
vector<int> g[5 + nmax];
int start[5 + nmax];

int euler[5 + 2 * nmax], level[5 + 2 * nmax], eulerpos;

inline void addnode(int node, int depth) {
  euler[++eulerpos] = node;
  level[eulerpos] = depth;
}

void dfs(int node, int depth) {
  addnode(node, depth);
  start[node] = eulerpos;
  for (int son : g[node]) {
    dfs(son, depth + 1);
    addnode(node, depth);
  }
}

const int LOG = 17;
int rmq[5 + LOG][5 + 2 * nmax], lg2[5 + 2 * nmax];
void calcrmq() { 
  for (int i = 1; i <= eulerpos; i++) {
    rmq[0][i] = i;
    if (i > 1)
      lg2[i] = 1 + lg2[i >> 1];
  }
  for (int i = 1; (1 << i) <= eulerpos; i++)
    for (int j = 1; j + (1 << i) - 1 <= eulerpos; j++) {
      int a = rmq[i - 1][j], b = rmq[i - 1][j + (1 << (i - 1))];
      rmq[i][j] = level[a] < level[b] ? a : b;
    }
}

inline int lca(int u, int v) {
  int l = start[u], r = start[v];
  if (l > r)
    swap(l, r);
  int lg = lg2[r - l + 1];
  int a = rmq[lg][l], b = rmq[lg][r - (1 << lg) + 1];
  return euler[level[a] < level[b] ? a : b];
}

int main() {
  ifstream fin("lca.in");
  ofstream fout("lca.out");
  int n, m;
  fin >> n >> m;
  for (int i = 2; i <= n; i++) {
    int t;
    fin >> t;
    g[t].push_back(i);
  }
  dfs(1, 0);
  calcrmq();
  while (m--) {
    int u, v;
    fin >> u >> v;
    fout << lca(u, v) << '\n';
  }
  return 0;
}