$dfs$ 序 + 树状数组.
- 由于路径的权是点权,可以考虑每个点被多少条路径经过,乘上它的点权即为贡献.
- 假设当前询问是在子树 $p$ 内,考虑一个点 $i$ ,在子树 $i$ 内与不在子树 $i$ 内的点形成了 $siz[i]\cdot (siz[p]-siz[i]+1)$ 条路径,都经过了点 $i$ .
- 还有一部分路径是将 $i$ 作为 $LCA$ 经过.显然每两个在 $i$ 的不同儿子形成的子树内的点都会经过 $i$ .这部分路径数目可以在 $dfs$ 时利用前缀和算出,记作 $k[i]$ .
- 由于修改只会单点修改点权,不改变树的形态,把那个 $siz[p]$ 拆出去算,预处理出每个点的剩下的系数.
- 直接利用 $dfs$ 序,树状数组维护答案.
- 记 $w[i]=k[i]+siz[i]\cdot (1-siz[u])$ .
- 那么每次询问的答案就是子树 $p$ 内的 $siz[p]\cdot (\sum siz[i]\cdot val[i])+(\sum w[i]\cdot val[i])$ .
- 开两个树状数组分别维护前缀 $\sum siz\cdot val$ 与 $\sum siz\cdot w$ 就好了.
1 |
|