树上差分

Posted by TH911 on May 16, 2025

树上差分

记 $f_x$ 表示节点 $x$ 的父节点。

点差分

记 $a_x$ 表示节点 $x$ 的点权。

那么当我们想要在树上的某一段路径上的点都加上 $1$ 的时候,一个一个暴力做效率就太过于低下,因此可以考虑差分。

记 $d$ 表示 $a$ 的差分数组,即:

\[d_x=a_x-\sum_{i\in son_x}a_i\]

这样,如果将 $p\sim q$ 路径上的所有点权都加 $1$,即:

\[d_p\leftarrow d_p+1\\ d_q\leftarrow d_q+1\\ d_{\operatorname{lca}(p,q)}\leftarrow d_{\operatorname{lca}(p,q)}-1\\ d_{f_{\operatorname{lca}(p,q)} }\leftarrow d_{f_{\operatorname{lca}(p,q)} }-1\]

边差分

边不好存储,因此可以考虑树型结构半线型的特征,将其转移到点上。

因为对于除根节点为的任意节点 $x$,边 $(x,f_x)$ 确定,因此可以记 $a_x$ 表示边 $(x,f_x)$ 的权值。

记 $d$ 为 $a$ 的差分数组,即:

\[d_x=a_x-\sum_{i\in son_x}a_i\]

此时再将 $p\sim q$ 路径上的点都加 $1$,即:

\[d_p\leftarrow d_p+1\\ d_q\leftarrow d_q+1\\ d_{\operatorname{lca}(p,q)}\leftarrow d_{\operatorname{lca}(p,q)}-2\]

差分还原

DFS 一遍即可。