我知道我的行为很↑↓,您们可以开骂(
思路是求两个点路径上深度最小值对应的结点
#include <set>
#include <cstdio>
#include <algorithm>
#define Ls(x) (node[x].ch[0])
#define Rs(x) (node[x].ch[1])
#define Fa(x) (node[x].fa)
const int N = 5e5 + 10;
struct Splay{ int ch[2], fa, revTag, mn, rmn, size; }node[N];
inline void pushup(int x)
{
node[x].size = (Ls(x) ? node[Ls(x)].size : 0) + (Rs(x) ? node[Rs(x)].size : 0) + 1;
if (node[Ls(node[Ls(x)].mn)].size < node[Ls(node[Rs(x)].mn)].size) node[x].mn = node[Ls(x)].mn;
else node[x].mn = node[Rs(x)].mn;
if (node[Rs(node[Ls(x)].rmn)].size < node[Rs(node[Rs(x)].rmn)].size) node[x].rmn = node[Ls(x)].rmn;
else node[x].rmn = node[Rs(x)].rmn;
if (node[Ls(x)].size < node[Ls(node[x].mn)].size) node[x].mn = x;
if (node[Rs(x)].size < node[Rs(node[x].rmn)].size) node[x].rmn = x;
}
inline void reverse(int x) { std::swap(Ls(x), Rs(x)); std::swap(node[x].mn, node[x].rmn); node[x].revTag ^= 1; }
inline void pushdown(int x)
{
if (!node[x].revTag) return ;
if (Ls(x)) reverse(Ls(x));
if (Rs(x)) reverse(Rs(x));
node[x].revTag = 0;
}
inline int get(int x) { return Rs(Fa(x)) == x; }
inline int nRoot(int x) { return Ls(Fa(x)) == x || Rs(Fa(x)) == x; }
inline void rotate(int x)
{
int fa = Fa(x), gf = Fa(fa), d = get(x), dd = get(fa);
if (nRoot(fa)) node[gf].ch[dd] = x;
node[fa].ch[d] = node[x].ch[d ^ 1]; Fa(node[x].ch[d ^ 1]) = fa;
node[x].ch[d ^ 1] = fa; Fa(fa) = x; Fa(x) = gf;
pushup(fa); pushup(x);
}
int st[N], tp;
inline void splay(int x)
{
int y = st[tp = 1] = x;
while (nRoot(y)) st[++tp] = y = Fa(y);
while (tp) pushdown(st[tp--]);
for (; nRoot(x); rotate(x))
if (nRoot(Fa(x))) rotate(get(x) == get(Fa(x)) ? Fa(x) : x);
pushup(x);
}
inline void access(int x)
{
int y = 0;
while (x) splay(x), Rs(x) = y, pushup(x), x = Fa(y = x);
}
inline void makeroot(int x) { splay(x); access(x); reverse(x); }
inline void split(int x, int y) { makeroot(x); access(y); splay(y); }
inline void link(int x, int y) { split(x, y); Fa(x) = y; }
int main()
{
int n, m, s; scanf("%d%d%d", &n, &m, &s); node[0].size = 2e9;
for (int i = 1, x, y; i < n; ++i) scanf("%d%d", &x, &y), link(x, y);
makeroot(s);
for (int i = 1, x, y; i <= m; ++i)
{
scanf("%d%d", &x, &y); split(x, y);
printf("%d\n", node[y].mn);
}
return 0;
}