树论

发布时间 2023-07-08 16:22:18作者: Eon_Sky

1. 重链剖分

1.1. 简介

重链剖分将树分割成若干链维护信息,将树的结构转换为线性结构,然后可用其他数据结构维护。

定义以下概念:

重子节点 轻子节点 重边 轻边 重链
某节点的子节点中子树大小最大的那个 某节点的子节点中的非重子节点 由某节点到其重子节点的连边 由某节点到其轻子节点的连边 若干条头尾相接的重边构成的链(落单的节点也看作一个重链

重链剖分有以下性质:

  1. 剖分时优先遍历重边,于是一条重链上的 DNF 序连续。
  2. 一颗子树内 DFN 序连续。

根据这两条性质我们可以考虑维两节点路径上的信息,与一个子树内的信息。路径上的信息可以用若干重链信息拼接而成维护,子树内则直接用一定范围内连续 DFN 的节点信息维护即可。

重链剖分同时可以解决求 LCA 问题,当然,这在维护路径上信息时就需要用到。对于两个节点,考虑将深度大的节点跳转至其所在重链顶点的父节点,进行此操作若干次直到两者在一条重链上。最后一个一个跳转即可。

1.2. 具体实现

实现时,维护以下变量:

\(fa_i\) \(dep_i\) \(siz_i\) \(hson_i\) \(top_i\) \(dfn_i\) \(rk_i\)
节点 \(i\) 的父节点 节点 \(i\) 的深度 节点 \(i\) 的子树大小 节点 \(i\) 的重子节点 节点 \(i\) 所在重链顶点 节点 \(i\) 的 DFN 序 DFN 序为 \(i\) 的节点编号

剖分操作需要进行两次 DFS:

  • 第一次 DFS 维护 \(fa_i,dep_i,siz_i,hson_i\)
  • 第二次 DFS 维护 \(top_i,dfn_i,rk_i\)