HDU5293 Tree chain problem

发布时间 2023-06-15 17:53:57作者: Schucking_Sattin

HDU5293 Tree chain problem

Solution 1

考虑 dp。把链的信息挂在深度最浅的节点上,自下而上更新答案。

\(f_u\) 表示 \(u\) 子树内的最大权值和,\(S\) 表示挂在 \(u\) 上的某条链,\(son(x)\) 表示点 \(x\) 的儿子集合,\(T_u\) 表示子树 \(u\) 的点集。

\(f_u\) 的初始值为:

\[f_u = \sum\limits_{v \in son(u)}f_{v} \]

考虑加链的转移为:

\[\begin{aligned} f_u &= \max\left( \sum\limits_{x \in T_u, x \not\in S}f_{x} + w_S \right) \\ &= \max\left( \left(\sum\limits_{x \in S}\sum\limits_{v \in son(x)}f_{v} \right) - \sum\limits_{x \in S, x \neq u}f_{x} + w_S \right) \\ \end{aligned} \]

观察发现双重和式中的内层可以在之前的更新中处理出来,即记 \(sum_u\) 表示 \(\sum\limits_{v \in son(u)}f_{v}\)

然后就转化成了树上单点修改 \(sum, f\) 的值,查询链的权值。

其实可以把 \(sum_v - f_v\) 看成整体在线段树上操作,然后在外面开数组维护具体值,以减小常数。

树链剖分 \(O(n\log^{2}{n})\)

Solution 2

依然是上面的式子,自下往上更新,但考虑维护一个点到根节点的 \(sum - f\) 的权值和,修改时对子树 \(u\) 内的节点都加上 \(sum_u - f_{u}\) 的贡献,子树恰好是一个连续的 dfn 序;查询时单点查询。

以上是 \(O(n\log{n})\) 的,可以线段树维护,也可以树状数组维护。