在树上对链上所有点 / 边加,最后查询每个点 / 边的权值。
树上点差分
记 \(a(u)\) 为点 \(u\) 的权值,记 \(d(u)\) 表示 \(a(u) - \sum_{v \in \operatorname{son}(u)} a(v)\)。
现在,我们对 \(s \rightsquigarrow t\) 这条链整体加上 \(x\)。
定义 \(s\) 和 \(t\) 的 LCA 是 \(p\)。则这个操作可以拆成三步:
- 对 \(s \rightsquigarrow p\) 这条链整体加上 \(x\)。
- 对 \(p \rightsquigarrow t\) 这条链整体加上 \(x\)。
- 对点 \(p\) 单点减去 \(x\)。
三步对差分数组的影响分别是:
- \(d(s)\) 多了 \(x\),\(d(\mathrm{fa}(p))\) 少了 \(x\)。
- \(d(t)\) 多了 \(x\),\(d(\operatorname{fa}(p))\) 少了 \(x\)。
- \(d(p)\) 少了 \(x\),\(d(\operatorname{fa}(p))\) 多了 \(x\)。
综合影响为:
- \(d(s)\) 多了 \(x\)。
- \(d(t)\) 多了 \(x\)。
- \(d(p)\) 少了 \(x\)。
- \(d(\operatorname{fa}(p))\) 少了 \(x\)。
这样链加就变成了四个单点加。所有链加结束后,将 \(d(u)\) 加上其所有子节点的权值就可以还原出 \(a(u)\)。
所以 dfs 一下就都能求出来了。
树上边差分
记 \(a(u, v)\) 为边 \((u, v)\) 的权值,记 \(d(u) = a(u, \operatorname{fa}(u)) - \sum_{v \in \operatorname{son}(u)}a(u, v)\)。
现在,我们对 \(s \rightsquigarrow t\) 这条链整体加上 \(x\)。
定义 \(s\) 和 \(t\) 的 LCA 是 \(p\)。则这个操作可以拆成两步:
- 对 \(s \rightsquigarrow p\) 这条链整体加上 \(x\)。
- 对 \(p \rightsquigarrow t\) 这条链整体加上 \(x\)。
两步对差分数组的影响分别是:
- \(d(s)\) 多了 \(x\),\(d(p)\) 少了 \(x\)。
- \(d(t)\) 多了 \(x\),\(d(p)\) 少了 \(x\)。
综合影响为:
- \(d(s)\) 多了 \(x\)。
- \(d(t)\) 多了 \(x\)。
- \(d(p)\) 少了 \(2x\)。
链加就变成了三个单点加。所有链加结束后,将 \((u, \mathrm{fa}(u))\) 这条边的权值设置为 \(d(u)\) 加上以 \(u\) 为根的子树内所有边权的和。
dfs 一下即可。