Advertisement
willy108

distance queries

Mar 7th, 2022
111
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.47 KB | None | 0 0
  1. //https://cses.fi/problemset/task/1135/
  2. //.19 seconds by c1729
  3.  
  4. #include <bits/stdc++.h>
  5. using namespace std;
  6.  
  7. inline void getnum(int &a) {
  8. int chr = getchar_unlocked();
  9. if (isspace(chr))
  10. chr = getchar_unlocked();
  11.  
  12. a = chr - '0';
  13. while (isdigit(chr = getchar_unlocked()))
  14. a = a * 10 + chr - '0';
  15. }
  16.  
  17. template <class T>
  18. struct RMQ {
  19. vector<vector<T>> jmp;
  20.  
  21. RMQ(const vector<T> &V) {
  22. int N = V.size(), on = 1, depth = 1;
  23. while (on < N)
  24. on *= 2, depth++;
  25. jmp.assign(depth, V);
  26. for (int i = 0; i < depth - 1; ++i)
  27. for (int j = 0; j < N; ++j)
  28. jmp[i + 1][j] = min(jmp[i][j],
  29. jmp[i][min(N - 1, j + (1 << i))]);
  30. }
  31.  
  32. T query(int a, int b) {
  33. assert(a < b); // or return inf if a == b
  34. int dep = 31 - __builtin_clz(b - a);
  35. return min(jmp[dep][a], jmp[dep][b - (1 << dep)]);
  36. }
  37. };
  38.  
  39. struct LCA {
  40. vector<int> time;
  41. vector<int> dist;
  42. RMQ<pair<int, int>> rmq;
  43.  
  44. LCA(vector<vector<int>> &C) : time(C.size(), -99), dist(C.size()), rmq(dfs(C)) {}
  45.  
  46. vector<pair<int, int>> dfs(vector<vector<int>> &C) {
  47. vector<tuple<int, int, int, int>> q(1);
  48. vector<pair<int, int>> ret;
  49. int T = 0, v, p, d;
  50. int di;
  51. while (!q.empty()) {
  52. tie(v, p, d, di) = q.back();
  53. q.pop_back();
  54. if (d)
  55. ret.emplace_back(d, p);
  56. time[v] = T++;
  57. dist[v] = di;
  58. for (auto e : C[v])
  59. if (e != p)
  60. q.emplace_back(e, v, d + 1, di + 1);
  61. }
  62. return ret;
  63. }
  64.  
  65. int query(int a, int b) {
  66. if (a == b)
  67. return a;
  68. a = time[a], b = time[b];
  69. return rmq.query(min(a, b), max(a, b)).second;
  70. }
  71.  
  72. int distance(int a, int b) {
  73. int lca = query(a, b);
  74. return dist[a] + dist[b] - 2 * dist[lca];
  75. }
  76. };
  77.  
  78. const int MAXN = 2e5;
  79. vector<vector<int>> tree;
  80.  
  81. int main() {
  82. int n, q;
  83. getnum(n), getnum(q);
  84. tree.resize(n);
  85. for (int i = 0; i < n - 1; ++i) {
  86. int a, b;
  87. getnum(a), getnum(b);
  88. tree[--a].push_back(--b);
  89. tree[b].push_back(a);
  90. }
  91.  
  92. LCA lca(tree);
  93. for (int i = 0; i < q; ++i) {
  94. int a, b;
  95. getnum(a), getnum(b);
  96. cout << lca.distance(--a, --b) << '\n';
  97. }
  98.  
  99. return 0;
  100. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement