其他分享
首页 > 其他分享> > CodeForces 1677D Tokitsukaze and Permutations

CodeForces 1677D Tokitsukaze and Permutations

作者:互联网

洛谷传送门

CF 传送门

还不错的一道思维 + 计数题。

思路

考虑一次操作后对 \(v\) 数组的影响:相当于将 \(v\) 数组左移一位,原本的 \(v_1\) 被覆盖了,\(v_n\) 补零,然后对于 \(i \in [1,n-1]\),\(v_i \gets \min(v_i - 1, 0)\)。同时还可以发现一个 \(v\) 数组对应着唯一一个排列。

考虑无解的情况:\(v\) 的后 \(k\) 位不是 \(0\),或者存在 \(i \in [1,n]\) 使得 \(v_i \ge i\)。特判掉即可,

接下来考虑对原来排列的 \(v'\) 计数(计算 \(v'\) 就相当于计算原来的 \(p\))。首先因为前 \(k\) 位被覆盖了,所以对于 \(i \in [1,k]\),\(v'_i\) 取 \([0,i-1]\) 的任意整数皆可。对于 \(i \in [k+1,n]\) 的 \(v'_i\):

乘法原理计算即可。

代码

code
/*

p_b_p_b txdy
AThousandMoon txdy
AThousandSuns txdy
hxy txdy

*/

#include <bits/stdc++.h>
#define pb push_back
#define fst first
#define scd second

using namespace std;
typedef long long ll;
typedef pair<ll, ll> pii;

const int maxn = 1000100;
const ll mod = 998244353;

ll n, m, a[maxn];

void solve() {
	scanf("%lld%lld", &n, &m);
	for (int i = 1; i <= n; ++i) {
		scanf("%lld", &a[i]);
	}
	for (int i = 1; i <= n; ++i) {
		if (a[i] >= i) {
			puts("0");
			return;
		}
	}
	for (int i = n - m + 1; i <= n; ++i) {
		if (a[i] > 0) {
			puts("0");
			return;
		}
	}
	ll ans = 1;
	for (int i = 1; i <= m; ++i) {
		ans = ans * i % mod;
	}
	for (int i = m + 1; i <= n; ++i) {
		if (a[i - m] == -1) {
			ans = ans * i % mod;
		} else if (a[i - m] == 0) {
			ans = ans * (m + 1) % mod;
		}
	}
	printf("%lld\n", ans);
}

int main() {
	int T = 1;
	scanf("%d", &T);
	while (T--) {
		solve();
	}
	return 0;
}

标签:typedef,txdy,int,ll,Permutations,Tokitsukaze,数组,1677D,define
来源: https://www.cnblogs.com/zltzlt-blog/p/16466680.html