1 条题解
-
0
自动搬运
来自洛谷,原作者为

寻逍遥2006
晓看天色暮看云,行也思君,坐也思君;春赏百花冬赏雪,醒也思卿,梦也思卿搬运于
2025-08-24 23:10:31,当前版本为作者最后更新于2025-02-27 21:59:38,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
原问题等价于对于每一个点 ,求树上包含 的所有树上独立集的最大点权之和。
测试点
暴力枚举派遣的队员的集合,如果其满足限制,则统计其贡献。
时间复杂度 。
测试点
先考虑只求解 号点。
尝试计算对于 ,包含 号点,且 的最大值恰好为 的独立集数量,考虑使用树形 DP:
设计 DP 状态 表示在 的子树内,选择一个 的最大值为 的集合,且不包含/包含 的集合数量。
求解 点的状态时依次将每一个儿子 合并。
具体的贡献形式有 $f_{i,j,0}\times (f_{v,k,0}+f_{v,k,1})\to f_{i,\max(j,k),0}$,。
单次合并时枚举 ,时间复杂度 。
最终 号点的答案就是 ,时间复杂度 。
对于每一个点进行这一过程,时间复杂度 。
测试点
上面的合并结构时 卷积,考虑较为一般的形式:
。
有 $\sum\limits_{k=1}^{m}h_k=\sum\limits_{k=1}^m\sum\limits_{\max(i,j)=k}f_ig_j=\sum\limits_{\max(i,j)\le m}f_ig_j=\left(\sum\limits_{i\le m}f_i\right)\left(\sum\limits_{j\le m}g_j\right)$。
因此,我们对 和 求前缀和,对位相乘,然后再做差分,就可以得到 。
这样单次合并的复杂度可以优化至 ,总时间复杂度优化到 。
测试点 另解
考虑放宽限制,计算对于 ,包含 号点,且 的最大值至多为 的独立集数量。
发现这时每一个点只有可以选择和不可选择两种状态,对于单个的 ,可以直接树形 DP 解决。
求解一个点的答案时间复杂度为 ,总时间复杂度为 。
测试点
考虑 从小到大的过程,每一个点有且仅有一次从不可选择到可选择的变化,因此考虑使用数据结构维护 DP 值变化的过程,这就是经典的动态 DP 问题。
使用树剖线段树总时间复杂度为 ,使用全局平衡二叉树时间复杂度为 ,但实现效率差距不大,可能需要卡常。
测试点
对于每一个点进行一次求解太麻烦了,发现 的两种做法都是可以使用换根 DP 进行求解,时间复杂度 。
测试点
注意到在上面的做法中,DP 状态第第二维实际上只与 的值域有关,更本质得说,只与本质不同的 的数量有关。
所以复杂度实际上是 的,其中 是本质不同的 的数量。
满分做法
使用转置原理求解这个问题。
考虑这样一个问题:记 为包含点 且 最大的点为 的独立集数量,那么记 阶方阵 。记向量 ,则我们要求的就是向量 。
考虑这个问题的转置,给每一个点设置一个额外的权值 ,记 ,考虑问题 。
这个问题就是:对于每一个 ,求所有 权值最大值等于 的独立集的 权值之和的和。
发现新问题是可以使用树剖线段树解决的。
考虑按照点的 权值从小到大一次加入每一个点。
实时维护 表示在 的子树内不包含/包含 的情况下,可能的独立集数量和 权值之和的和。
事实上 是一个二元组 。
对其进行的加法和乘法运算分别为 $(cnt_1,val_1)+(cnt_2,val_2)=(cnt_1+cnt_2,val_1+val_2)$,$(cnt_1,val_1)\times (cnt_2,val_2)=(cnt_1\times cnt_2,cnt_1\times val_2+cnt_2\times val_1)$。
首先考虑转移:
$f_{i,0}=\prod\limits_{v\in son_i}(f_{v,1}+f_{v,0}),f_{i,1}=op_i\prod\limits_{v\in son_i}f_{v,0}$。
其中 在 还没有出现过是为 ,在 出现过之后为 ,单独将重儿子 提取出来,此时记 为除 之外的所有儿子,那么就可以得到矩阵转移:
$\begin{bmatrix}f_{i,0}\\f_{i,1}\end{bmatrix}=\begin{bmatrix}\prod\limits_{v\in son_i}(f_{v,0}+f_{v,1})&\prod\limits_{v\in son_i}(f_{v,0}+f_{v,1})\\op\prod\limits_{v\in son_i}f_{v,0}&0\end{bmatrix}\begin{bmatrix}f_{u,0}\\f_{u,1}\end{bmatrix}$
不妨记这个矩阵为 。每一次修改相当于修改一个点 的 ,考虑修改之后,矩阵 会发生变化的位置只有 到根的路径上跳轻边跳到的点,根据重链剖分的性质,这样个点只有 个。
对于每一个节点建立维护 矩阵中的两个连乘 和 的线段树,这样就能够支持对于单个轻儿子的 的修改。
同时对于每一条重链维护矩阵 的线段树,这样边能够支持对于单个 的修改以及链顶节点的 值得查询。
具体的修改过程,就是根据计算出的 和 的值更新新的 。就可以通过整条链上面的矩阵来计算出新的 和 ,然后就可以更新 的线段树,以此类推一直更新到 和 。
因此按照 从小到大修改每一个 ,每一次修改后 的增加量就是所有包含 且以 为最大值的独立集数量以及重量之和。
假设每 次修改之后 的值为 。
那么对于第 小的来说答案就是 的第二维。
发现所有对于第二维的操作都是形如 的操作,所以对其进行转置操作有 。
对于第二维的加法,都可以写成 的形式,因此转置之后有 ,减法同理。
对于第二维的乘法,可以写成 $val_3\gets val_3+val_1\times cnt_2+val_2\times cnt_1$ 的形式,因此转置之后有 ,。
因此可以直接封装出所有操作的逆,然后倒序执行之前执行过的所有操作即可。
时间复杂度 ,空间复杂度 或 。
可以将树剖线段树替换成全局平衡二叉树,将时间复杂度优化至 ,但实际效率差距不大。
- 1
信息
- ID
- 11557
- 时间
- 2000ms
- 内存
- 512MiB
- 难度
- 7
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者