关于树形背包时间复杂度为什么会比想象中少一阶
Upd 2024年12月18日
将树拍到 DFS 序上,合并两个子树时认为复杂度是左子树 DFS 序最大的 \(V\) 个点和右子树 DFS 序最小的 \(V\) 个点个数相乘,则整个序列中只有下标差 \(\le 2V-1\) 的点对有贡献,所以是 \(O(nV)\)。
Upd 2022年10月3日
对于树上的任意一点 \(x\),我们设其贡献的时间复杂度为 \(T(x)\)。
设 \(x\) 的儿子大小分别是 \(p_1,\dots,p_c\),设 \(x\) 的大小为 \(p_0=1+\sum_{i=1}^cp_i\),则
\[\begin{aligned}
T(x)=&1
\\&+p_1
\\&+p_2(1+p_1)
\\&+p_3(1+p_1+p_2)
\\&+\dots
\\&+p_c(1+p_1+\dots+p_{c-1})
\\=&1+\frac{(1+\sum_{i=1}^cp_i)^2-1-\sum_{i=1}^cp_i^2}{2}
\\=&\frac{1}{2}
(1+p_0^2-\sum_{i=1}^cp_i^2)\end{aligned}
\]
发现不论以什么顺序合并儿子复杂度都是相同的。
总复杂度
\[\sum_{i=1}^n T(i)=\frac{1}{2}(n+n^2)
\]
相当于把 \(-p_i^2\) 这部分负贡献给这个儿子,抵消后只剩根节点 \(\text{size}\) 的平方了。
远古
下面的东西太 naive 了,差不多别看了,谢谢。

思路来自 Konata,有删改及本作者的想法。
如果正常想,每个节点都要进行 \(O(n^2)\) 的背包,则时间复杂度为 \(O(n^3)\),其实不然。
假设 \(n\) 个节点的树形背包的时间复杂度为 \(f(n)\)。
那么假设根节点下面的子树大小分别为 \(p_1,p_2,\dots,p_k\),子树大小 \(p_i\) 对应的子树根节点下面的子树大小分别为 \(g_{i,1},g_{i,2},\dots,g_{i,s_i}\)。
\[\begin{aligned}f(n)
&=\sum\limits^k_{i=1}f(p_i)+\sum\limits^k_{i=2}\left(p_i\times\sum\limits^{i-1}_{j=1}p_j\right)
\\
& = \sum\limits^k_{i=1}f(p_i)+\sum\limits_{1\leqslant i<j\leqslant k}p_i\times p_j
\\
& = \sum\limits^k_{i=1}f(p_i)+\dfrac{\left(\sum\limits^k_{i=1}p_i\right)^2-\sum\limits^k_{i=1}p_i^2}{2}
\\
& = \dfrac{1}{2}(n-1)^2+\sum\limits^k_{i=1}f(p_i)-\dfrac{1}{2}\sum\limits^k_{i=1}p_i^2
\\
& \leqslant \dfrac{1}{2}n^2+\sum\limits^k_{i=1}(f(p_i)-\dfrac{1}{2}p_i^2)
\\
& = \dfrac{1}{2}n^2+\sum\limits^k_{i=1}(\dfrac{1}{2}(p_i-1)^2+\sum\limits^{s_i}_{j=1}(f(g_{i,j})-\dfrac{1}{2}g_{i,j}^2)-\dfrac{1}{2}p_i^2)
\\
& \leqslant \dfrac{1}{2}n^2+\sum\limits^k_{i=1}\sum\limits^{s_i}_{j=1}(f(g_{i,j})-\dfrac{1}{2}g_{i,j}^2)
\\
& \leqslant \dfrac{1}{2}n^2+\sum\sum\dots\sum(f(\dots)-\dfrac{1}{2}(\dots)^2)
\\
& \leqslant \dots
\\
& \leqslant \dfrac{1}{2}n^2
\\
& =O(n^2)
\end{aligned}\]
特殊得,如果背包的容量上限为 \(V\),则总时间复杂度为 \(O(nV)\)。
作者:ShaoJia,欢迎分享本文,转载时敬请注明原文来源链接。

 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号