Alex_tz307

LCA

Aug 16th, 2021
593
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 1.46 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. ifstream fin("lca.in");
  6. ofstream fout("lca.out");
  7.  
  8. const int NMAX = 2e5 + 5;
  9. int N, Q, M, tour[NMAX], depth[NMAX], first[NMAX], lg2[NMAX], rmq[18][NMAX];
  10. vector<int> G[NMAX];
  11.  
  12. void dfs(int u, int level) {
  13.   tour[++M] = u;
  14.   depth[M] = level;
  15.   first[u] = M;
  16.   for (int v : G[u]) {
  17.     dfs(v, level + 1);
  18.     tour[++M] = u;
  19.     depth[M] = level;
  20.   }
  21. }
  22.  
  23. void compute_rmq() {
  24.   for (int i = 2; i <= M; ++i)
  25.     lg2[i] = lg2[i >> 1] + 1;
  26.   for (int i = 1; i <= M; ++i)
  27.     rmq[0][i] = i;
  28.   for (int i = 1; (1 << i) < M; ++i)
  29.     for (int j = 1; j <= M - (1 << i); ++j) {
  30.       int l = 1 << (i - 1);
  31.       rmq[i][j] = rmq[i - 1][j];
  32.       if (depth[rmq[i - 1][j + l]] < depth[rmq[i][j]])
  33.         rmq[i][j] = rmq[i - 1][j + l];
  34.     }
  35. }
  36.  
  37. int lca(int u, int v) {
  38.   int x = first[u], y = first[v];
  39.   if (x > y)
  40.     swap(x, y);
  41.   int diff = y - x + 1;
  42.   int l = lg2[diff];
  43.   int sol = rmq[l][x];
  44.   int shift = diff - (1 << l);
  45.   if (depth[sol] > depth[rmq[l][x + shift]])
  46.     sol = rmq[l][x + shift];
  47.   return tour[sol];
  48. }
  49.  
  50. void solve() {
  51.   fin >> N >> Q;
  52.   for (int u = 2; u <= N; ++u) {
  53.     int t;
  54.     fin >> t;
  55.     G[t].emplace_back(u);
  56.   }
  57.   dfs(1, 0);
  58.   compute_rmq();
  59.   for (int q = 0; q < Q; ++q) {
  60.     int u, v;
  61.     fin >> u >> v;
  62.     fout << lca(u, v) << '\n';
  63.   }
  64. }
  65.  
  66. void close_files() {
  67.   fin.close();
  68.   fout.close();
  69. }
  70.  
  71. int main() {
  72.   solve();
  73.   close_files();
  74.   return 0;
  75. }
  76.  
Advertisement
Add Comment
Please, Sign In to add comment