【模板】动态DP&对于树链剖分的一些思考&全局平衡二叉树


链分治

链分治就是树链剖分。

在需要回答在子树/或结点到根路径查询时,由于 d f s dfs dfs序的连续性,可以用到树链剖分将复杂度降到 l o g 2 n log^2n log2n

先不考虑具体如何维护每个点的 d p dp dp值,假设转移是 O ( 1 ) O(1) O(1)的,可以用线段树维护,那么修改某个点的 d p dp dp值实际上就是修改了它到根路径上的值,查询答案即为根结点上的值。

在链分治后,只会跳 l o g n logn logn次链,每次链内/链与链交接处都可以 l o g n logn logn修改。


动态DP

查询操作

求树上的最大权独立集的权值大小。

f [ x ] [ 1 / 0 ] f[x][1/0] f[x][1/0]分别表示选/不选点 x x x时, x x x子树上的最大权独立集的权值大小,

正常的 D P DP DP转移:
f [ x ] [ 0 ] = m a x y ∈ s o n x ( f [ y ] [ 0 ] , f [ y ] [ 1 ] ) f[x][0]=max_{y\in son_x}(f[y][0],f[y][1]) f[x][0]=maxysonx(f[y][0],f[y][1])
f [ x ] [ 1 ] = v a l x + m a x y ∈ s o n x f [ y ] [ 0 ] f[x][1]=val_x+max_{y\in son_x}f[y][0] f[x][1]=valx+maxysonxf[y][0]

为了达到每次链内/链与链交接处都可以 l o g n logn logn修改,我们显然不能对于每个点逐个儿子的转移,而需要把信息压成重儿子和轻儿子两部分。

g [ x ] [ 1 / 0 ] g[x][1/0] g[x][1/0]分别表示不考虑重儿子情况下,选/不选点 x x x时, x x x子树上的最大权独立集的权值大小。

现在的 D P DP DP转移:
f [ x ] [ 0 ] = g [ x ] [ 0 ] + m a x ( f [ s o n x [ 0 ] , f [ s o n x ] [ 1 ] ] ) f[x][0]=g[x][0]+max(f[son_x[0],f[son_x][1]]) f[x][0]=g[x][0]+max(f[sonx[0],f[sonx][1]])
f [ x ] [ 1 ] = g [ x ] [ 1 ] + f [ s o n x ] [ 0 ] f[x][1]=g[x][1]+f[son_x][0] f[x][1]=g[x][1]+f[sonx][0]

似乎可以 O ( 1 ) O(1) O(1)合并了,线性的加和取 m a x max max

考虑维护连续的一段线性的加和取 m a x max max的方法,我们联想到了矩阵。

上述转移可以仿照 F l o y d Floyd Floyd的形式写成矩阵乘法:
[ f [ x ] [ 0 ] f [ x ] [ 1 ] ] = [ g [ x ] [ 0 ] g [ x ] [ 0 ] g [ x ] [ 1 ] − i n f ] × [ f [ s o n x ] [ 0 ] f [ s o n x ] [ 1 ] ] \left[ \begin{matrix} f[x][0] \\ f[x][1] \end{matrix} \right]= \left[ \begin{matrix} g[x][0]& g[x][0]\\ g[x][1] & -inf \end{matrix} \right]\times \left[ \begin{matrix} f[son_x][0]\\ f[son_x][1] \end{matrix} \right] [f[x][0]f[x][1]]=[g[x][0]

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值