Upd 2024年12月18日
将树拍到 DFS 序上,合并两个子树时认为复杂度是左子树 DFS 序最大的 V 个点和右子树 DFS 序最小的 V 个点个数相乘,则整个序列中只有下标差 ≤2V−1 的点对有贡献,所以是 O(nV)。
Upd 2022年10月3日
对于树上的任意一点 x,我们设其贡献的时间复杂度为 T(x)。
设 x 的儿子大小分别是 p1,…,pc,设 x 的大小为 p0=1+∑ci=1pi,则
T(x)=1+p1+p2(1+p1)+p3(1+p1+p2)+…+pc(1+p1+⋯+pc−1)=1+(1+∑ci=1pi)2−1−∑ci=1p2i2=12(1+p20−c∑i=1p2i)
发现不论以什么顺序合并儿子复杂度都是相同的。
总复杂度
n∑i=1T(i)=12(n+n2)
相当于把 −p2i 这部分负贡献给这个儿子,抵消后只剩根节点 size 的平方了。
远古
下面的东西太 naive 了,差不多别看了,谢谢。

思路来自 Konata,有删改及本作者的想法。
如果正常想,每个节点都要进行 O(n2) 的背包,则时间复杂度为 O(n3),其实不然。
假设 n 个节点的树形背包的时间复杂度为 f(n)。
那么假设根节点下面的子树大小分别为 p1,p2,…,pk,子树大小 pi 对应的子树根节点下面的子树大小分别为 gi,1,gi,2,…,gi,si。
f(n)=k∑i=1f(pi)+k∑i=2(pi×i−1∑j=1pj)=k∑i=1f(pi)+∑1⩽i<j⩽kpi×pj=k∑i=1f(pi)+(k∑i=1pi)2−k∑i=1p2i2=12(n−1)2+k∑i=1f(pi)−12k∑i=1p2i⩽12n2+k∑i=1(f(pi)−12p2i)=12n2+k∑i=1(12(pi−1)2+si∑j=1(f(gi,j)−12g2i,j)−12p2i)⩽12n2+k∑i=1si∑j=1(f(gi,j)−12g2i,j)⩽12n2+∑∑…∑(f(…)−12(…)2)⩽…⩽12n2=O(n2)
特殊得,如果背包的容量上限为 V,则总时间复杂度为 O(nV)。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义