又是一个水蓝题 好像不难 为什么我不会
首先要注意到a想要有答案必须满足这样的条件:
0≤ai+1−ai≤2
0≤ai+1−ai 是因为每一个小于等于 i 的数肯定小于等于 i+1 。
ai+1−ai≤2 是因为在 1 到 i 中大于 i 且小于等于 i+1 的数只可能有一个(也就是 i+1 )然后你再把一个小于 i+1 的数放在 i+1 这个位置,差值就达到了最大的 2 。
那对于从 1 到 n−1 的每个i我们来分别讨论三种情况:
-
ai+1−ai=0 :在i+1这个位置放入了一个比i+1大的数,答案不变。
-
ai+1−ai=1 :i+1 放入 [1,i] 或者一个小于 i+1 的数放入 i+1 这个位置,对答案的贡献分别是 (i−ai) 和 (i+1−ai) 。
-
ai+1−ai=2 : i+1被放入[1,i] 且一个小于 i+1 的数放入 i+1 这个位置,对答案的贡献分别是 (i−ai) 和 (i+1−ai−1)。
然后从前往后乘一下做完了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| #include<bits/stdc++.h> using namespace std; #define int long long const int mod = 998244353; void solve() { int n; cin >> n; vector<int> a(n + 1); for (int i = 1; i <= n; i++) { cin >> a[i]; } if (a[1] > 1) { cout << 0 << '\n'; return; } int ans = 1; for (int i = 1; i < n; i++) { if (a[i + 1] - a[i] < 0 || a[i + 1] - a[i] > 2) { ans = 0; break; } if (a[i + 1] - a[i] == 1) { ans = (ans * ((i - a[i]) + (i + 1 - a[i]))) % mod; } else if (a[i + 1] - a[i] == 2) { ans = ((ans * (i - a[i])) % mod * (i + 1 - a[i] - 1)) % mod; } } cout << (a[n] == n ? ans : 0) << '\n'; return; } signed main() { int T; cin >> T; while (T--) { solve(); } return 0; }
|