1. 程式人生 > 其它 >【計蒜客7月提高組模擬賽B】劍鬼

【計蒜客7月提高組模擬賽B】劍鬼

\(\texttt{計蒜客7月提高組模擬賽 } \text{劍鬼}\)

定義兩棵二叉樹相同,當且僅當:

  1. 兩棵樹都是空的(空樹也是二叉樹),或者
  2. 它們的左右兒子分別相同

對於兩棵 不同 的二叉樹,它們之間的好壞關係定義為:

  1. 如果這兩棵二叉樹大小不同,則大小更大的那個更好;
  2. 如果這兩棵二叉樹的左兒子不同,則左兒子更好的那個更好;
  3. 否則這兩棵二叉樹誰更好等價於它們的右兒子誰更好。

給出定一棵二叉樹,求比它壞的二叉樹個數。答案對 \(10^9+7\) 取模。

不妨令 \(rt\)​ 為樹根, \(ls(x)\)​ 代表 \(x\)​ 的左兒子, \(rs(x)\)​ 代表 \(x\)​ 的右兒子, \(sz(x)\)

​ 代表以 \(x\)​ 為根節點的子樹的大小, \(H\)​ 為卡特蘭數。

首先給出一個基本的結論,沒有限制時, \(n\)​​​​​ 個沒有差別的點可以構成 \(H(n)\)​​​​​​ 個不同的二叉樹​。事實上,注意到遞推式以及初值與卡特蘭數相符即證。

\(f(x)\)​​ 代表與以 \(x\)​​​​​​​ 為根節點的子樹大小相等的更差的數目,它由以下不重複的情況構成

  1. 子樹的左子樹更優秀且左子樹的大小與子樹的大小相等,這部分的答案為

    \[f(ls(x))H(sz(rs(x))) \]
  2. 子樹的左子樹更優秀且左子樹的大小與子樹的大小不相等,這部分的答案為

    \[\sum\limits_{i=0}^{sz(ls(x))-1}H(i)H(sz(x)-1-i) \]
  3. 左子樹優秀度相等且子樹的右子樹更優秀,這部分的答案為

\[f(rs(x)) \]

最後的答案即

\[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))\)

的時候,我們可以計算出

\[\sum\limits_{i=sz(ls(x))}^{sz(x)-1}H(i)H(sz(x)-1-i) \]

二者相減即可。現在分析加上這個優化後的複雜度:

對每一個點考慮它會對時間複雜度產生多大貢獻。自下而上地,一個點如果想對時間複雜度產生 \(1\)​​ 的貢獻,則其所在子樹大小至少會增大 \(2\)​​ 倍。因此一個點最多對時間複雜度產生 \(\log n\)​​ 的貢獻,故總時間複雜度為 \(O(n \log n)\)​​​​ 。

\(\square\)