树上背包复杂度证明

树上背包复杂度证明

参考

树上背包上下界优化。

考虑 vu 的儿子,现在 fu 已经合并了若干个 v 前面的子树,(不包含 v 及以后的子树)其大小为 sxv 子树的大小为 sv

考虑转移 gu,i+jfu,i+fv,j,然后 fu,igi

考虑 g 第二维的范围是 [0,su+sv]fu 第二维的范围是 [0,su]fv 第二维的范围是 [0,sv]

枚举 i,j 使得一定满足这些范围即可。

考虑这次合并的时间复杂度 O(susv),那么在 u 此处合并子树的时间复杂度就是不断将 sv 加入 su 产生 susv 的代价,那么把 u 所有子树都合并起来的时间复杂度就是其所有子树大小(再加上它本身的一个 1)两两乘积的和。

这个总和怎么计算?考虑每一个点对都会在 LCA 处贡献一个 1,所以时间复杂度是 O(n2)


如果对背包的第二维进行一个 k 的限制,复杂度是什么呢?

考虑称子树大小 k 的为小子树,>k 的为大子树。

考虑小子树之间合并为极大的小子树(定义为再往父亲走一步就变为大子树)的复杂度,根据定义所有极大的小子树是不会互相包含的:

首先,合并得到一个大小为 x 的极大的小子树的复杂度是 O(x2),因为此时第二维没有了限制,相当于上一个问题。

假设极大的小子树的大小是 x1,x2,,其和 n,它们的平方和最大就是每个 x 尽可能地取 k 也就是 k2×nk=O(nk)

然后考虑极大的小子树合并为极小的大子树(定义为极大的小子树的父亲)。

假设极大的小子树的大小是 x1,x2,,其和 n,那么将它们合并到父亲的代价 kxink

最后是极小的大子树之间的合并,前面已经算完了极大的小子树之间都合并完的代价,现在只剩下了若干极小的大子树,并且它们互相不包含。所以它们个数最多 nk 个,而每次合并的代价为 k2,总代价就是 O(nk)

综上所述,该树上背包的复杂度为 O(nk)

2023.8.3 upd 一个更简洁的证明

多个子树可以三度化掉(当然这只是把树上背包合并的过程显式体现而已)在 dfs 序上考虑,合并子树看作合并这 dfs 序上相邻的两个区间,看作前面选择一个长度为 x 的后缀,后面选择一个长度为 y 的前缀,满足 x+yk,它们拼成一个区间,方案数是多少。一个区间最多只会被拼出一次(也就是仅会在与它有交的子树都合并在一起的那一次被统计到),所以直接大力放缩成 dfs 序中所有长度 k 的区间,即得 O(nk) 的上界。

posted @   do_while_true  阅读(472)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?

This blog has running: 1837 days 12 hours 56 minutes 35 seconds

点击右上角即可分享
微信分享提示