俗話說的好:“打表出奇蹟”,所以我們這一題打表計算。
其實確實可以打表來找規律。透過打表,我們可以獲得如下的結果:
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;
}