算法总结-重链剖分

· · 算法·理论

算法总结 - 重链剖分

概念

重链剖分

用处:

  1. 将树划分成不超过 \log{n} 条连续的链
  2. 通过节点的 DFS 序,使树上的节点形成一个连续的序列,便于维护树上的修改操作。

实现:

  1. ```cpp void dfs1(int x,int f){ dep[x]=dep[f]+1; fa[x]=f; siz[x]=1; for(int i=0;i<e[x].size();i++){ int y=e[x][i]; if(y==f) continue; dfs1(y,x); siz[x]+=siz[y]; if(siz[son[x]]<siz[y]) son[x]=y;//更新重儿子 } return ; } ```
  1. 1. $dfn$ 数组:记录每个结点搜到的顺序,也就是 DFS 序。 2. $val$ 数组:按 DFS 序存储每个节点的点权。 ```cpp void dfs2(int x,int t){ top[x]=t; dfn[x]=++did; val[did]=a[x]; if(!son[x]) return ;//没重儿子说明也没有轻儿子 dfs2(son[x],t); for(int i=0;i<e[x].size();i++){ int y=e[x][i]; if(y==fa[x]||y==son[x]) continue; dfs2(y,y); } return ; } ```

运用

树链剖分求 LCA

维护树上操作

原题

  1. xy 路径上所有节点的权值都加上 z

  2. xy 路径上所有节点的权值之和。

  3. x 的子树内所有节点的权值都加上 z

  4. x 的子树内所有节点的权值之和。

发现一处错误:图树链剖分 - dfs 序 on 2025.10.25,待修改。

update on 2025.10.26,修改了笔误与错误图片,更新和优化了理解性内容,补全了操作 34

To Be Continue