Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //https://cses.fi/problemset/task/1135/
- //.19 seconds by c1729
- #include <bits/stdc++.h>
- using namespace std;
- inline void getnum(int &a) {
- int chr = getchar_unlocked();
- if (isspace(chr))
- chr = getchar_unlocked();
- a = chr - '0';
- while (isdigit(chr = getchar_unlocked()))
- a = a * 10 + chr - '0';
- }
- template <class T>
- struct RMQ {
- vector<vector<T>> jmp;
- RMQ(const vector<T> &V) {
- int N = V.size(), on = 1, depth = 1;
- while (on < N)
- on *= 2, depth++;
- jmp.assign(depth, V);
- for (int i = 0; i < depth - 1; ++i)
- for (int j = 0; j < N; ++j)
- jmp[i + 1][j] = min(jmp[i][j],
- jmp[i][min(N - 1, j + (1 << i))]);
- }
- T query(int a, int b) {
- assert(a < b); // or return inf if a == b
- int dep = 31 - __builtin_clz(b - a);
- return min(jmp[dep][a], jmp[dep][b - (1 << dep)]);
- }
- };
- struct LCA {
- vector<int> time;
- vector<int> dist;
- RMQ<pair<int, int>> rmq;
- LCA(vector<vector<int>> &C) : time(C.size(), -99), dist(C.size()), rmq(dfs(C)) {}
- vector<pair<int, int>> dfs(vector<vector<int>> &C) {
- vector<tuple<int, int, int, int>> q(1);
- vector<pair<int, int>> ret;
- int T = 0, v, p, d;
- int di;
- while (!q.empty()) {
- tie(v, p, d, di) = q.back();
- q.pop_back();
- if (d)
- ret.emplace_back(d, p);
- time[v] = T++;
- dist[v] = di;
- for (auto e : C[v])
- if (e != p)
- q.emplace_back(e, v, d + 1, di + 1);
- }
- return ret;
- }
- int query(int a, int b) {
- if (a == b)
- return a;
- a = time[a], b = time[b];
- return rmq.query(min(a, b), max(a, b)).second;
- }
- int distance(int a, int b) {
- int lca = query(a, b);
- return dist[a] + dist[b] - 2 * dist[lca];
- }
- };
- const int MAXN = 2e5;
- vector<vector<int>> tree;
- int main() {
- int n, q;
- getnum(n), getnum(q);
- tree.resize(n);
- for (int i = 0; i < n - 1; ++i) {
- int a, b;
- getnum(a), getnum(b);
- tree[--a].push_back(--b);
- tree[b].push_back(a);
- }
- LCA lca(tree);
- for (int i = 0; i < q; ++i) {
- int a, b;
- getnum(a), getnum(b);
- cout << lca.distance(--a, --b) << '\n';
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement