题目
DreamGrid has an interesting permutation of (1,2,...,n) denoted by (a_1,a_2,...a_n).
- For each (1 le i le n), (f_i = max{a_1,a_2...,a_i}).
- For each (1 le i le n), (g_i = min{a_1,a_2...,a_i}).
- For each (1 le i le n), (h_i = f_i - g_i).
Given the sequence h, please calculate the number of different permutations that can generate the sequence h. Print the answer modulo (10^9+7).
思路
一开始想歪想复杂了。(h_i)代表最大值和最小值之间的差值,这个差值代表可以选择的数字数。维护一个可选数字数cnt。当(h_i > h_{i-1}),说明当前位是前缀的最大值或最小值,所以(ans=2 imes ans),(cnt = cnt + (h_i - h_{i-1} - 1));当(h_i == h_{i-1}),说明当前位置可以选一个数字放进去,所以(ans=cnt imes ans),(cnt = cnt - 1)。
一开始特判一些不合法的情况,然后就可以求解了。
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
const int INF = 0x3f3f3f3f;
typedef long long ll;
const int M = 1e9 +7;
#define endl '
'
int h[N];
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while(t--) {
int n;
cin >> n;
bool ok = true;
for(int i = 1; i <= n; i++) {
cin >> h[i];
if(i > 1 && h[i] < h[i - 1] || h[i] >= n) ok = false;
}
if(h[1] != 0) ok = false;
else if(h[n] != n - 1) ok = false;
else if(n > 1 && h[2] == 0) ok = false;
if(!ok) cout << 0 << endl;
else {
int cnt = 0;
ll ans = 1;
for(int i = 2; i <= n; i++) {
if(h[i] > h[i - 1]) {
cnt += h[i] - h[i - 1] - 1;
ans = ans * 2 % M;
} else {
ans = ans * cnt % M;
cnt--;
}
}
cout << ans << endl;
}
}
}