据说这东西猫锟在WC2018讲过,怎么一点印象都没有呢?当时应该是在冬眠
NOIP2018T6如果用动态dp去看就是一道裸题,不过因为询问是相互独立的,即修改没有时效性,可以直接用倍增代替动态dp。
先看一道题:
如果没有修改,这题就是树形dp入门题:没有上司的晚会
设 f ( x , 0 / 1 ) f(x,0/1) f(x,0/1)分别表示以x为根的子树中,选x的最大独立集,不选x的最大独立集。
则:
f ( x , 0 ) = ∑ y ∈ s o n ( x ) m a x ( f ( y , 0 ) , f ( y , 1 ) ) f(x,0)=\sum_{y∈son(x)}max(f(y,0),f(y,1)) f(x,0)=∑y∈son(x)max(f(y,0),f(y,1))
f ( x , 1 ) = v [ x ] + ∑ y ∈ s o n ( x ) f ( y , 0 ) f(x,1)=v[x]+\sum_{y∈son(x)}f(y,0) f(x,1)=v[x]+∑y∈son(x)f(y,0)
现在我们要修改一个点x的权值v,这个修改显然只会影响到x到root路径上所有点的f,问题在于如何做到快速修改。
既然是修改一条路径,我们可以想想树链剖分。
设 g ( x , 0 / 1 ) g(x,0/1) g(x,0/1),意义是x为根的子树中,把重儿子的子树删掉的x选(1)/不选(0)的最大独立集。
对于一条x到root路径的修改, g g g受到影响的显然只有x和每条重链顶的父亲。
由于重链只有log条,所以这里暴力修改即可。
那么问题在于如何快速进行重链上的dp转移,先写一下转移:
f ( i , 0 ) = g ( i , 0 ) + m a x ( f ( i + 1 , 0 ) , f ( i + 1 , 1 ) ) f(i,0)=g(i,0)+max(f(i+1,0),f(i+1,1)) f(i,0)=g(i,0)+max(f(i+1,0),f(i+1,1))
f ( i , 1 ) = g ( i , 1 ) + f ( i + 1 , 0 ) f(i,1)=g(i,1)+f(i+1,0) f(