1. 程式人生 > >[BZOJ5305][Haoi2018]蘋果樹(組合數學+dp)

[BZOJ5305][Haoi2018]蘋果樹(組合數學+dp)

Address

洛谷P4492
BZOJ5305
LOJ#2526

Solution

好像只有我一人用這種無腦做法,果然蒟蒻
首先,一棵 N N 個節點的二叉樹中有 N N 個可以插入新葉子節點的位置。
所以一共會生成 N

! N! N N 個節點的不同的二叉樹。
所以,此題從期望題變成了計數題:求生成的所有二叉樹的所有無序點對的路徑長度之和。
定義狀態:
f [
i ] f[i]
表示 i i 個節點生成的所有二叉樹的所有無序點對的路徑長度之和。
g [
i ] g[i]
表示 i i 個節點生成的所有二叉樹,根到每個點的路徑長度之和。
邊界:
f [ 0 ] = g [ 0 ] = 0 f[0]=g[0]=0
而一棵二叉樹能被生成,當且僅當每個節點的編號都大於其父親節點編號。
轉移先列舉左子樹的點數 j j ,而根必須放最小的編號,所以需要在 i 1 i-1 個節點中選出 j j 個節點放進左子樹,其餘的放進右子樹,即 C i 1 j C_{i-1}^j
先討論 g g
(1)先考慮根的左子節點到其子樹內所有點的距離和加上根的右子節點到其子樹內所有點的距離和。當左子樹的形態確定時,右子樹不管是 ( n 1 j ) ! (n-1-j)! 種形態中的哪一種,左子節點到其子樹內所有點的距離之和都不變,對於右子樹的形態確定時也一樣。也就是:
g [ j ] × ( i 1 j ) ! + g [ i 1 j ] × j ! g[j]\times(i-1-j)!+g[i-1-j]\times j!
(2)對於整棵樹的每一種形態,這棵樹除了根之外的 i 1 i-1 個節點走到根都必須經過連線根和其子節點的恰好一條邊。所以需要加上的貢獻為:
( i 1 ) × i ! (i-1)\times i!
所以:
g [ i ] = ( i 1 ) × i ! + j = 0 i 1 { C i 1 j × ( g [ j ] × ( i 1 j ) ! + g [ i 1 j ] × j ! ) } g[i]=(i-1)\times i!+\sum_{j=0}^{i-1}\{C_{i-1}^j\times(g[j]\times(i-1-j)!+g[i-1-j]\times j!)\}
f f 的轉移比較複雜。
(1)和 g g 一樣,把兩棵子樹的距離之和合並起來:
f [ j ] × ( i 1 j ) ! + f [ i 1 j ] × j ! f[j]\times(i-1-j)!+f[i-1-j]\times j!
(2)兩個端點分別來自兩個子樹的路徑長度之和。
當左子樹確定時,右子樹有 f [ i 1 j ] f[i-1-j] 種確定方案,左子樹內的一個點可以和右子樹內的 i 1 j i-1-j 個點配成路徑計入貢獻,同時需要考慮:左子樹內的每一個點到根時都需要經過連線根的左子節點和其父親的邊。右子樹確定時同理。
( g [ j ] + j ! × j ) × ( i 1 j ) ! × ( i 1 j ) + ( g [ i 1 j ] + ( i 1 j ) ! × ( i 1 j ) ) × j ! × j (g[j]+j!\times j)\times(i-1-j)!\times(i-1-j)+(g[i-1-j]+(i-1-j)!\times(i-1-j))\times j!\times j
(3)根到每個點的路徑長度,即 g [ i ] g[i] 在轉移完 j j 後加上。
所以:
f [ i ] = g [ i ] + j = 0 i 1 { C i 1 j × ( f [ j ] × ( i 1 j ) ! + f [ i 1 j ] × j ! f[i]=g[i]+\sum_{j=0}^{i-1}\{C_{i-1}^j\times(f[j]\times(i-1-j)!+f[i-1-j]\times j!
+ ( g [ j ] + j ! × j ) × ( i 1 j ) ! × ( i 1 j ) + ( g [ i 1 j ] + ( i 1 j ) ! × ( i 1 j ) ) × j ! × j ) } +(g[j]+j!\times j)\times(i-1-j)!\times(i-1-j)+(g[i-1-j]+(i-1-j)!\times(i-1-j))\times j!\times j)\}