树上差分 学习笔记

在树上对链上所有点 / 边加,最后查询每个点 / 边的权值。

树上点差分

\(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 一下即可。

例题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值