struct LCA {
struct edge {
int from, to, w, nxt;
} edges[maxn << 3];
int head[maxn << 1], cnt1;
int id[maxn << 1], in[maxn << 1], Dep[maxn << 1], Dist[maxn << 1], cnt2;
int RMQ[maxn << 1][25];
int vis[maxn];
void addedge(int u, int v, int w) {
edges[cnt1] = { u,v,w,head[u] };
head[u] = cnt1++;
}
void init() {
mem(head, -1);
cnt1 = cnt2 = 0;
}
void DFS(int u, int f, int d, int dis) {
vis[u] = 1;
in[++cnt2] = u;
Dep[cnt2] = d;
id[u] = cnt2;
Dist[u] = dis;
for (int i = head[u]; i != -1; i = edges[i].nxt) {
int v = edges[i].to;
if (vis[v]) continue;
DFS(v, u, d + 1, dis + 1);
in[++cnt2] = u;
Dep[cnt2] = d;
}
}
void initRMQ() {
for (int i = 1; i <= cnt2; i++)
RMQ[i][0] = i;
for (int j = 1; (1 << j) <= cnt2; j++) {
for (int i = 1; i + (1 << j) - 1 <= cnt2; i++) {
int x = RMQ[i][j - 1];
int y = RMQ[i + (1 << (j - 1))][j - 1];
RMQ[i][j] = Dep[x] < Dep[y] ? x : y;
}
}
}
int getLCA(int a, int b) {
int k, x, y;
a = id[a]; b = id[b];
if (a > b)swap(a, b);
k = log(1.0 + b - a) / log(2.0);
x = RMQ[a][k];
y = RMQ[b - (1 << k) + 1][k];
return Dep[x] < Dep[y] ? in[x] : in[y];
}
int getdist(int x, int y) {
return Dist[x] + Dist[y] - 2 * Dist[getLCA(x, y)];
}
}L;