前不久,WC2019考了一道风格新奇的数树。
通过层层容斥化式猜结论,(子任务2)终于化简成了一道小清新树形DP:
一个边集T的权值等于每个连通块的权值之积,每个连通块的权值等于 k × k× k×联通块大小,求所有边集的权值之和。一个简单的实现方式是直接 d p dp dp,令 d p ( i , j ) dp(i,j) dp(i,j)表示划分到了 i i i这个子树, i i i所在的联通大小为 j j j时的所有边集权值之和,直接实现的复杂度是 O ( n 2 ) O(n^2) O(n2)的并不能通过 n = 1 0 5 n=10^5 n=105的诡异数据。
且不看最后一句话,这段话差点让我。。。。。。怎么 O ( n 2 ) O(n^2) O(n2)DP啊,一个n枚举点,一个n枚举当前大小,一个n枚举增加的大小,这活脱脱的 O ( n 3 ) O(n^3) O(n3)?然后我就naive了。原来大佬早有证明。具体是这样的,合并大小为a,b的子树复杂度是 O ( a b ) O(ab) O(ab),可以看成a子树内任选一点,b子树内任选一点进行匹配,不管怎么合并任意两个点只会在其lca匹配一次,所以是 O ( n 2 ) O(n^2) O(n2)的。
所以我的树形DP都白学了。。。。。。
其次,如果第二位大于k的部分不需要,那么复杂度是 O ( n k ) O(nk) O(nk)的
这就导致2018九省联考秘密袭击这道题的 O ( n 2 k ) O(n^2k) O(n2k)大力树上DP远远快于我的 O ( n 2 log 2 n ) O(n^2\log^2 n) O(n2log2n)的FFT和 O ( n 2 log n ) O(n^2\log n) O(n2logn)的线段树合并维护整体DP+拉格朗日插值 O ( n 2 ) O(n^2)