題目連結:
題目大意:
給定一正整數 T( T ≦ 2 ^ 20 ),代表接下來有 T 筆測試資料。
每筆測試資料會有一正整數 N ( N ≦ 2 ^ 20 ),求有 N 個節點的二元樹之數量(互相對稱的,各自算一種),並將結果取 10 ^ 9 + 7 的餘數並輸出。
範例輸入:
3
1
2
3
範例輸出:
1
2
5
解題思維:
N 個節點可以組成的二元樹共有:
而因為有 T 筆的 N 值,且 T 、 N 皆 ≦ 2 ^ 20。因此可以先將 N = 1 ~ 2 ^ 20 的所有情況都先跑過一次。
根據上面的式子,當我們知道 N = K - 1 的方法數,並要求得 N = K 時:只要把 N = K - 1 的方法數乘以 (2K) × (2K - 1) 並除以 K × (K + 1)。
但是因為我們是要求除以 10 ^ 9 + 7 的餘數,而我們的算式裡又有除法。因此需要求 (K × (K + 1)) 對於 10 ^ 9 + 7 的模反元素,這樣子就不需要除法了。整體的式子就變為:
N = K - 1 的方法數乘以 (2K) × (2K - 1)
並乘以 K × (K + 1) 的模反元素
然後在中途計算的時候,都各自取一次餘數,即是正確的結果。
而模反元素可以藉由
擴展歐幾里得算出,其方法跟求最大公因數類似。只是要儲存倍數的關係,再輾轉相除。
此次分享到此為止,如有任何更加簡潔的想法或是有說明不清楚之地方,也煩請各位大大撥冗討論。