关于动态树(LCT)

前置

\(Splay\) 维护序列(保证每棵树的复杂度)

应用场景

  • 路径修改
  • 子树修改
  • 路径查询
  • 子树查询
  • (断开/连接)一条边

虚实链剖分

考虑为何树剖无法完成应用:
树剖刻意选择了重儿子,在断边连边时重儿子会变,不方便维护
LCT于是进行了虚实链剖分,随意选择实儿子,没有要求,随意选取

辅助树

由于会有断边操作,所以会出现森林的情况,使用多个\(Splay\)维护每条链上信息,构成辅助树

  1. 辅助树由\(Splay\)变成,应该在每个节点都有唯一对应的\(Splay\)节点

  2. 所有点最多一个实儿子

  3. 虚边上认父不认子,即可以找到\(v\) 的父亲是\(u\),但是无法找到 \(u\) 的儿子是 \(v\)

image

原树的根不等于辅助树的根,
原树的边不等于辅助树的边,
原树每个点的父亲与辅助树中不一定相同。

声明变量:

  • Son[u][0/1] 表示左右儿子。
  • Fa[u] 表示一个点的父亲.
  • Sum[u] 点到根的权值和
  • Val[u] 点权
  • Siz[u] 辅助树的子树大小
  • Tag[u] 表示该点是否已经翻转

函数声明:

  1. pushup 放下去
inline void pushup(int u){
	Siz[u]=Siz[ls]+Siz[rs]+1;
}
  1. Isroot判断是否是splay的根
inline bool Isroot(int u){
	return (Son[Fa[u]][0]!=u&&Son[Fa[u]][1]!=u);
}
posted @ 2026-02-04 07:24  rerecloud  阅读(1)  评论(0)    收藏  举报