首页 > 其他分享 >ARC139D

ARC139D

时间:2022-09-28 08:24:21浏览次数:51  
标签:tmp int 端点 ans ARC139D mul mod

所有数的和可以转化为对于每个 \(1\le i\le m\),计算有多少个数 \(\ge i\) 即可。
开始时先找到 \(\ge i\) 的左端点,然后考虑这个左端点的移动,先考虑开始时在 \(x\) 右边,那么如果放 \([1,i−1]\),那么位置不变,如果放 \([i,m]\),那么就左移动一格。在 \(x\) 左边同理。
那么直接枚举多少次操作使得左端点改变,计算方案数即可。

Code:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2005, mod = 998244353;
int C[N][N], mul[N][N];

void prework(int n) {
	for (int i = 0; i <= n; ++i) {
		C[i][0] = 1;
		for (int j = 1; j <= i; ++j) C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % mod;
	}
	for (int i = 0; i <= n; ++i) {
		mul[i][0] = 1;
		for (int j = 1; j <= n; ++j) mul[i][j] = 1ll * mul[i][j - 1] * i % mod;
	}
}

int n, m, k, X, ans, cnt[N];

int main() {
	scanf("%d%d%d%d", &n, &m, &k, &X);
	for (int i = 1, x; i <= n; ++i) scanf("%d", &x), ++cnt[x];
	for (int i = 1; i <= m; ++i) cnt[i] += cnt[i - 1];
	prework(2000);
	for (int i = 1; i <= m; ++i) {
		int tot = cnt[i - 1];
		for (int j = 0; j <= k; ++j) {
			int tmp = C[k][j];
			if (tot >= X) tmp = 1ll * tmp * mul[i - 1][k - j] % mod * mul[m - i + 1][j] % mod * min(n - X + 1, n - (tot - j)) % mod;
			else tmp = 1ll * tmp * mul[m - i + 1][k - j] % mod * mul[i - 1][j] % mod * max(n - X + 1, n - (tot + j)) % mod; 
			ans = (ans + tmp) % mod;
		}
	}
	printf("%d", ans);
	return 0;
}

标签:tmp,int,端点,ans,ARC139D,mul,mod
From: https://www.cnblogs.com/Kobe303/p/16736684.html

相关文章

  • 【题解】ARC139D Priority Queue 2
    ?思路来源题意假设初始时有一个长度为\(N\),值域为\(M\)的数组\(A\)。现在要进行\(K\)次操作,每次操作从\([1,M]\)中选取一个数,并将其加入\(A\)中。单次操作完......