Problem
最大连通子块和
Description
给出一棵个点,以为根的有根树,点有点权。
要求支持如下两种操作:
- :将点的点权改为
- :求以为根的子树的最大连通子块和
一棵子树的最大连通子块和指该子树所有子连通块的点权和中的最大值(本题中子连通块包括空连通块,点权和为)。
Input
第一行两个整数,,表示树的点数以及操作的数目。
第二行个整数,第个整数表示第个点的点权。
接下来的行,每行两个整数,表示和之间有一条边相连。
接下来的行,每行输入一个操作,含义如题目所述。
保证操作为或之一。
Output
对于每个操作输出一行一个整数,表示询问子树的最大连通子块和。
Sample Input
1 | 5 4 |
Sample Output
1 | 4 |
HINT
,任意时刻 。
Source
CQzhangyu
&GXZlegend
原创
标签:树链剖分
树上DP
Solution
经典树链剖分维护树上。以下解法源自出题人CQzhangyu的博客和GXZlegend的博客。
首先考虑暴力,令表示子树中包含的连通块权值和最大值,那么。维护表示子树中连通块权值和最大值,则。每次修改后重新,可做到。
注意到每次修改后不是所有的都变化。用树链剖分维护树上,可以每次不修改所有的值。然而直接维护的值不方便,因为递推式中的和式在线段树上不便于计算。于是引入,其中是的轻儿子。那么重链上的转移就变为。这其实就是最大连续子段和的方式,可以用线段树维护带修改最大连续子段和。于是对于每次修改,向上跳重链,在线段树上每条重链的区域内维护最大连续子段和即可。注意这里“每条重链的区域”指的是链顶到链底的距离,而非括号序列。
再考虑如何维护。注意到每次都直接取最值,带修改后,其实是可删除堆的形式。对每个点维护可删除堆来维护轻儿子的值最大值,对于重儿子则在线段树上维护。在线段树上修改后时,用每个结点的堆顶元素更新最大子段和,即可动态维护。
查询时,直接向上跳重链,将该重链对应区间的最大子段和取出来打擂即可。
这样修改复杂度,查询复杂度,总复杂度。
Code
1 |
|