CF1677D Tutorial
Aleph_Drawer · · 题解
我是 *2500 都不会的傻子。这题还是挺套路的题。
首先很容易注意到一个
首先注意到必须满足
考虑题目描述的流程在做什么事情。本质上就是一次“冒泡”的过程。简单观察一下,考虑一个数
有了这个就相当好做了。首先检查
我们已经知道一次“冒泡”操作是
首先我们要整体右移,然后在第一个位置补上一个
事实上,我们只需要计数,那么我们并不需要模拟上述过程。
我们只需要考虑
哎呀,语言表述真是稀碎。看代码得了。
// Author : Aleph_Drawer
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6 + 105;
const ll MOD = 998244353;
int t;
int n, k;
int v[N];
int main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
cin >> t;
for(; t; --t) {
cin >> n >> k;
for(int i = 1; i <= n; i++)
cin >> v[i];
ll ans = 1;
for(int i = 1; i <= n; i++) {
if(v[i] >= i) ans = 0;
}
for(int i = n; i >= n - k + 1; i--)
if(v[i] != 0 && v[i] != -1) ans = 0;
if(ans == 0) {
cout << "0\n"; continue;
}
for(int i = 1; i <= k; i++)
ans *= i, ans %= MOD;
for(int i = 1; i <= n - k; i++) {
if(v[i] == -1) ans *= (i + k), ans %= MOD;
if(v[i] == 0) ans *= (k + 1), ans %= MOD;
}
cout << ans << '\n';
}
return 0;
}