树链问题合集

树上差分

给一条链(u,v)加1,在u处+1,v处+1,LCA处-2。
用树状数组在dfs序上单点修改单点查询,但是修改是往前贡献,查询是往后查询, O ( n l o g n ) O(nlogn) O(nlogn)
如果询问都在修改之后可以直接树形DP由下往上传, O ( n ) O(n) O(n)
eg:BZOJ3631: [JLOI2014]松鼠的新家

查询一个点到根的路径的和

有时候链上问题可以转化成两点和lca到根的路径和问题。
如果是单点修改,用树状数组在dfs序上对子树差分,单点查询(即前缀和), O ( n l o g n ) O(nlogn) O(nlogn)
eg:BZOJ2819: Nim
如果还有子树修改,考虑修改一个点 x x x对它的子树中点 y y y的贡献:

  • 单点修改 x x x,加上 a a a,贡献为 a a a
  • 子树修改 x x x,子树加上 a a a,贡献为 a ∗ ( d e e p [ y ] − d e e p [ x ] + 1 ) = a ∗ d e e p [ y ] + a ∗ ( 1 − d e e p [ x ] ) a*(deep[y]-deep[x]+1)=a*deep[y]+a*(1-deep[x]) a(deep[y]deep[x]+1)=adeep[y]+a(1deep[x])

维护两个树状数组,一个存直接贡献(单点修改的a和子树修改的a*(1-deep[x])),一个存间接贡献(子树修改的a,求后乘上对应的deep)即可。
eg:BZOJ4034: [HAOI2015]树上操作

万能解法:树链剖分+线段树

无论是求和、异或、最大值、最小值、颜色段数、单点修改、子树修改、链修改统统一套搞定。

对一个点所有儿子子树做不同修改:

只对重儿子做修改,轻儿子就在查询时往上跳链,加上链顶的父亲未做的修改贡献。见CF1254D Tree Queries

链并

求几个点到根的链并可以将点按dfs序排序后每个点+1,相邻两点LCA-1。
求几条树链的并可以把每条链按树链剖分取dfs序区间,然后求区间并。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值