【計蒜客7月提高組模擬賽B】劍鬼
\(\texttt{計蒜客7月提高組模擬賽 } \text{劍鬼}\)
定義兩棵二叉樹相同,當且僅當:
- 兩棵樹都是空的(空樹也是二叉樹),或者
- 它們的左右兒子分別相同
對於兩棵 不同 的二叉樹,它們之間的好壞關係定義為:
- 如果這兩棵二叉樹大小不同,則大小更大的那個更好;
- 如果這兩棵二叉樹的左兒子不同,則左兒子更好的那個更好;
- 否則這兩棵二叉樹誰更好等價於它們的右兒子誰更好。
給出定一棵二叉樹,求比它壞的二叉樹個數。答案對 \(10^9+7\) 取模。
不妨令 \(rt\) 為樹根, \(ls(x)\) 代表 \(x\) 的左兒子, \(rs(x)\) 代表 \(x\) 的右兒子, \(sz(x)\)
首先給出一個基本的結論,沒有限制時, \(n\) 個沒有差別的點可以構成 \(H(n)\) 個不同的二叉樹。事實上,注意到遞推式以及初值與卡特蘭數相符即證。
設 \(f(x)\) 代表與以 \(x\) 為根節點的子樹大小相等的更差的數目,它由以下不重複的情況構成
-
子樹的左子樹更優秀且左子樹的大小與子樹的大小相等,這部分的答案為
\[f(ls(x))H(sz(rs(x))) \] -
子樹的左子樹更優秀且左子樹的大小與子樹的大小不相等,這部分的答案為
\[\sum\limits_{i=0}^{sz(ls(x))-1}H(i)H(sz(x)-1-i) \] -
左子樹優秀度相等且子樹的右子樹更優秀,這部分的答案為
最後的答案即
\[f(rt)+\sum\limits_{i=0}^{sz(rt)-1}H(i) \](計蒜客上的資料統計答案時沒考慮空樹,所以最後要 -1)
第一種情況和第三種情況處理起來都是比較簡單的,因為我們知道卡特蘭數的簡單封閉形式,可以通過預處理階乘及其逆元 \(O(1)\) 樸素轉移。
對於第二種情況,我們考慮一個看似沒用的小優化,就是分類討論 \(sz(ls(x))\) 與 \(sz(rs(x))\) 的大小關係,因為我們知道
\[\sum\limits_{i=0}^{sz(x)-1}H(i)H(sz(x)-1-i)=H(sz(x)) \]在 \(sz(ls(x))>sz(rs(x))\)
二者相減即可。現在分析加上這個優化後的複雜度:
對每一個點考慮它會對時間複雜度產生多大貢獻。自下而上地,一個點如果想對時間複雜度產生 \(1\) 的貢獻,則其所在子樹大小至少會增大 \(2\) 倍。因此一個點最多對時間複雜度產生 \(\log n\) 的貢獻,故總時間複雜度為 \(O(n \log n)\) 。
\(\square\)