// compile: make data
// run: ./data < data.in
#include <bits/stdc++.h>
using namespace std;
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
#ifdef LOCAL
#include <debug/codeforces.h>
#define debug(x...) _debug_print(#x, x);
#define Debug(x...) _debug_print_format(#x, x);
#else
#define debug(x...)
#define Debug(x...)
#endif
template<typename...Args> void print_(Args...args){((cout<<args<<" "),...)<<endl;}
#define VI vector<int>
#define VII vector<vector<int>>
#define VIII vector<vector<vector<int>>>
#define rep(i,a,b) for(int i=(a);i<(int)(b);++i)
#define sz(v) ((int)(v).size())
#define print(...) print_(__VA_ARGS__);
#define FIND(a, x) ((find(a.begin(),a.end(),(x))!=a.end())?1:0)
#define cmin(x,...) x=min({(x), __VA_ARGS__})
#define cmax(x,...) x=max({(x), __VA_ARGS__})
#define INTMAX (int)(9223372036854775807)
#define INF (int)(1152921504606846976)
#define NaN (int)(0x8b88e1d0595d51d1)
#define double long double
#define int long long
#define MAXN 200010
struct tree {
int n;
vector<vector<int>> e;
struct node {
vector<node*> ch;
node* parent = nullptr;
int size, depth;
};
vector<node> vertex;
node *root;
tree(int V) {
n = V;
e.resize(n);
vertex.resize(n);
}
void add_edge(int u, int v) {
e[u].push_back(v), e[v].push_back(u);
}
int ind(node *x) {return x - &vertex[0]; }
void build(int rt = 0) {
function<void(int, int)> dfs = [&](int u, int pre) {
vertex[u].size = 1;
vertex[u].depth = u==ind(root) ? 0 : vertex[u].parent->depth + 1;
for (int v: e[u]) {
if (v == pre) continue;
vertex[u].ch.push_back(&vertex[v]);
vertex[v].parent = &vertex[u];
dfs(v, u);
vertex[u].size += vertex[v].size;
}
};
root = &vertex[rt];
dfs(rt, -1);
}
vector<vector<int>> hp;
vector<vector<int>> ancestor() {
vector<vector<int>> p(n, vector<int>(log2(n) + 1));
rep(i, 0, n) p[i][0] = vertex[i].parent ? ind(vertex[i].parent) : -1;
rep(j, 1, log2(n)+1) rep(i, 0, n) p[i][j] = ~p[i][j-1] ? p[p[i][j-1]][j-1] : -1;
return p;
}
int lca(int u, int v) {
if (!hp.size()) hp = ancestor();
if (vertex[u].depth < vertex[v].depth) swap(u, v);
for (int k = log2(n); k >= 0; --k) if (vertex[u].depth - (1<<k) >= vertex[v].depth) u = hp[u][k];
if (u == v) return u;
for (int k = log2(n); k >= 0; --k) {
if (hp[u][k] != hp[v][k]) {
u = hp[u][k], v = hp[v][k];
}
}
return hp[u][0];
}
void graphviz_dump(int plus = 0, string filename = "graph.dot") {
FILE *f = fopen(filename.c_str(), "w");
fprintf(f, "digraph Tree {\n");
rep(i, 0, n) {
node *x = &vertex[i];
fprintf(f, " %lld;\n");
}
rep(i, 0, n) {
node *x = &vertex[i];
for (auto y: x->ch) {
fprintf(f, " %ld -> %ld;\n", x - &vertex[0], y - &vertex[0]);
}
}
fprintf(f, "}\n");
}
int query(int u, int v) {
int p = lca(u, v);
return vertex[u].depth + vertex[v].depth - 2 * vertex[p].depth;
}
};
int32_t main() {
ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
int n, q; cin >> n >> q;
tree g(n);
rep(i, 0, n-1) {
int u, v; cin >> u >> v; --u, --v;
g.add_edge(u, v);
}
g.build(0);
while (q--) {
int u, v; cin >> u >> v; --u, --v;
cout << g.query(u, v) << '\n';
}
return 0;
}
Yo, check out superjiliapp! Heard it’s the real deal for gaming on the go. Gonna give it a shot tonight, wish me luck!
Yo 55666 bong88, need a reliable access point to Bong88. You got what I need? Fast, secure, and always up. Get in the game: 55666 bong88
Yo, Goldsbetgame caught my eye. I went through it and noticed some games I think are fire, I’m gonna see if it’s worth more time. goldsbetgame
Casinoplusph – pretty solid option, especially if you’re looking for something local. The mobile experience is really smooth too. Gave me a few lucky nights. Check it out at casinoplusph
Alright, heard the buzz about kkkjili29. Decided to give it a whirl. Surprisingly user-friendly and the bonuses were decent. Gonna keep playing around on this one. Sign up today at kkkjili29
BG786, might be a new favorite. Simple, clean, and fast payouts. What more could you ask for? Feels like a solid place to spend some time. Give it a look at bg786
Really enjoying the variety of games available here. Everything loads quickly and the gameplay is fair. bh999game is my new favorite spot to unwind.
Very reliable platform with a wide range of payment methods. Everything is transparent and fast. I trust rupiahbetlogin completely.