关于 LCT 求 LCA
  • 板块学术版
  • 楼主zhiyangfanshotacon
  • 当前回复14
  • 已保存回复14
  • 发布时间2021/12/11 10:02
  • 上次更新2023/11/3 22:31:49
查看原帖
关于 LCT 求 LCA
137603
zhiyangfanshotacon楼主2021/12/11 10:02

我知道我的行为很↑↓,您们可以开骂(

思路是求两个点路径上深度最小值对应的结点

#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;
}
2021/12/11 10:02
加载中...