P8474 「GLR-R3」立春 題解

Night_Tide發表於2024-09-26

俗話說的好:“打表出奇蹟”,所以我們這一題打表計算。

其實確實可以打表來找規律。透過打表,我們可以獲得如下的結果:

1	1
2	3
3	21
4	315
5	9765
……	……

然後觀察可得:

\[1 \times 3 = 1 \times (2^2 - 1) = 3 \]

\[3 \times 7 = 3 \times (2^3 - 1) = 21 \]

\[21 \times 15 = 21 \times (2^4 - 1) = 315 \]

\[315 \times 31 = 315 \times (2^5 - 1) = 9765 \]

於是可以猜測,設 \(f_i\)\(n = i\) 時的答案,則有 \(f_i = f_{i - 1}\times (2^i - 1)\)

這樣就可以 \(O(n)\) 遞推了。

但是我們還需要知道的是,為什麼是這樣的關係。

假設我們已經知道了 \(n = i - 1\) 時的答案,現在需要求出 \(n = i\) 時的答案。

顯然,一個 \(i\) 的排列可以向一個 \(i - 1\) 的排列中的一個位置插入數 \(i\) 來得到,由於一個 \(i - 1\) 的排列中不會有大於 \(i\) 的數,所以對於任意一個 \(i - 1\) 的排列,從後往前插入數 \(i\) 依次會增加 \(0,1,2,\dots,i - 1\) 個逆序對。

所以,\(f_i = f_{i - 1} \times (2^0,2^1,2^2,\dots,2^{i - 1}) = f_{i - 1} \times (2^i - 1)\)

#include<bits/stdc++.h>
#define MOD 1000000007
using namespace std;
typedef long long ll;
int n;
ll ans = 1, bit = 4;
int main(){
    scanf("%d",&n);
    for(int i = 2; i <= n; i++, (bit <<= 1) %= MOD){
        (ans *= (bit - 1)) %= MOD;
    }
    printf("%lld\n",ans);
    return 0;
}