30pts玄关求调
查看原帖
30pts玄关求调
1036180
ChampionCyan楼主2024/7/22 11:48
#include <bits/stdc++.h>
#define int long long
using namespace std;

const int MAXN = 1000005;
const int MOD = 998244353;

inline int read() {
	int x = 0, f = 1;
	char ch = getchar();
	while (ch < '0' || ch > '9') {
		if (ch == '-')
			f = -1;
        ch = getchar();
	}
	while (ch >= '0' && ch <= '9')
		x = (x << 1) + (x << 3) + ch - '0', ch = getchar();
	return x * f;
}

int n = read(), m = read(), op = read();

inline int power(int a, int b) {
	int res = 1;
    while (b) {
        if (b & 1)
            res = (res * a) % MOD;
        a = (a * a) % MOD;
        b >>= 1;
    }
    return res;
}

int a[MAXN], b[MAXN], y[MAXN], x[MAXN];

inline int A(int n, int m) {
	if (n < m)
		return 0;
    return y[n] * x[n - m] % MOD;
}

inline int C(int n, int m) {
	if (n < m)
        return 0;
    return y[n] * x[n - m] % MOD * x[m] % MOD;
}

inline void solve1() {
	int sum = 0;
	for (int i = 1; i <= n; i++)
		sum += a[i];
	if (sum > m) {
		puts("0");
        return;
	}
	int A = (m - sum) + n, ans = 1;
	for (int i = A; i > A - n; i--)
		ans = ans * i % MOD;
	printf("%lld\n", ans);
}

int G[2005], S[1005];

inline void solve2() {
	if (n == 1) {
		printf("%lld\n", m);
        return;
	}
	int sum = 0;
	y[0] = x[0] = 1;
	for (int i = 1; i <= m; i++)
		y[i] = y[i - 1] * i % MOD, x[i] = power(y[i], MOD - 2);
	for (int i = 1; i <= n; i++)
		sum += a[i];
	int ans = 0;
	for (int i = 1; i <= n; i++) {
		for (int j = 0; j <= 1000; j++)
			G[b[i] + j] = (G[b[i] + j] + S[j]) % MOD;
		S[b[i]]++;
	}
	for (int i = 0; i <= 2000; i++)
		if (G[i])
			ans = (ans + G[i] * A(m + i - sum + n, n) % MOD) % MOD;
	printf("%lld\n", ans * power(C(n, n - 2), MOD - 2) % MOD);
}

signed main() {
	for (int i = 1; i <= n; i++)
		b[i] = read(), a[i] = (b[i] << 1) - 1, b[i]--;
	if (op)
		solve1();
	else
		solve2();
	return 0;
}
2024/7/22 11:48
加载中...