LOJ6733 人造情感 / 3.14 校内考试 灵活性(flexibility)
给你一颗 \(n\) 个节点的树,以及 \(m\) 条路径 \((u, v, w)\),其中 \(w\) 可以认为是 \((u, v)\) 这题路径被标记的一个权值。一个路径集合 \(S\) 的重量 \(W(S)\) 记为:找出 \(S\) 的一个权值之和最大的子集,该子集满足任何两条路径没有公共点,这个子集的所有路径权值之和就是 \(W(S)\)。
记 \(f(u, v) = w\) 为最小的非负整数 \(w\),使得对于给定的 \(m\) 条边组成的路径集合 \(U\),\(W(U \cup \{(u, v, w + 1)\}) > W(U)\) 。
请你计算下式,对 \(998244353\) 取模。
\[\sum_{u=1}^n \sum_{v=1}^n f(u, v) \]\(n \le 3 \times 10^5, 0 \le m \le 3\times 10^5, 1 \le w \le10^9\)。
数据结构
动态规划
首先考虑怎么计算 \(W(U)\),我们可以设 \(f(x)\) 表示仅考虑 \(x\) 为根的子树,不管 \(x\) 的选择情况的最大权值,\(g(x)\) 表示仅考虑 \(x\) 为根的子树,\(x\) 必须是空的收益,然后我们可以设 \(c(x) = g(x) - f(x)\) 表示把 \(x\) 空出来的代价,然后有转移:
然后 \(c(x)\) 可以理解为加上 \(c(x)\) 后 \(f(x)\) 就是 \(\sum_{y \in son_x} f_y\) 了,于是 \(x\) 不选了。
接着考虑 \(W(U \cup \{u, v, w +1\})\) 怎么求,那么如果 \(\mathrm{lca}(u, v) = 1\),那么答案就是 $f(1)+ \sum_{k \in \mathrm{path}(u, v)} c_k $。
但是如果不满足上面的条件,令 \(t = \mathrm{lca}(u, v)\),那么就可能会存在一条路径使得其从上面经过了 \(t\),然后我们要将贡献消除,于是我们可以设 \(h(x)\) 表示对于不存在从 \(x\) 父亲到 \(x\) 子树的路径被选的情况下,\(f(1)\) 的最大值,假设当前考虑的节点为 \(x\),那么有转移(默认转移是取 \(\max\)):
第一个转移显然可以直接赋值,第二个转移,我们要考虑在一条路径 \((u_i, v_i)\) 上面打上 \(h(x) + \sum_{k\in \mathrm{path}(u_i, v_i)} c_k + w_i\) 的标记,然后将它传下去取 \(\max\),同时有不能传到路径上面的点。
如果是暴力,可以考虑每个点维护一个 tuple(w, a, b)
表示权值为 \(w\) 的 tag
,并且不能传到 \(a, b\) 两个儿子(如果没有这么多限制,直接赋值为 \(0\) 即可),然后将所有标记 sort
一遍,对于每个点暴力从大到小扫一遍,直到找到第一个满足条件的最大的,因为每个标记最多被扫到 \(2\) 遍,因此复杂度为 \(\mathcal O(\sum 标记之和)\) 的。
然后我们可以使用线段树 + 树剖优化这个过程,因为很多标记都是赋值为 \((w, 重儿子, 0)\) 的形式,因此可以树剖维护对于每个点,这种标记的最大值(也就是这种标记中只取最大的一个),每次操作只有重链顶端要单独赋值,于是总的标记个数就是 \(\mathcal O(m \log n + n)\) 的了。
求出 \(h(x)\) 之后,对于 \((u, v)\) 的答案就是 \(f(1) - \left(h(\mathrm{lca}(u, v)) + \sum_{k \in \mathrm{path}(u, v)} c_k\right)\) 了,后面的式子就是在满足 \(\{u, v \}\) 所在联通块没有被占领的情况下的最大值,那么答案就是这个式子了。
具体细节看代码。