HDU5293 Tree chain problem
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})\) 的,可以线段树维护,也可以树状数组维护。