1 条题解
-
0
自动搬运
来自洛谷,原作者为

COsm0s
知耻而后勇。搬运于
2025-08-24 23:03:11,当前版本为作者最后更新于2024-08-25 21:45:51,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
题目里有“恰好”的标志,套路的,我们可以将它转化为至多/至少后再容斥回来。
当我们已经确定 个 固定在这个数中时,我们发现,剩余的 个数就可以随便选——前提是不能有 。
也就是说,在剩余的数随便选时,我们可能会多选若干个 。
很容易想到这可以转化成“至少”的形式。
那么问题就转化成了两部分:
-
随便选剩余的数。
-
由“至少”推向“恰好”。
我们先来看第一部分。
当确定 个 时,我们有 个空可以插入那些随便选的数字。
举个例子:
x2023x2023x2023x其中
x代表的是一堆随便选的数字。这是个经典的隔板法,讲这些数字分到 个空的方案数为 :
又因为题目明示了我们前导零的合法,所以再乘上每个数都有的 的 种方案数,即为随便选的数的方案。
第二部分,直接套公式即可。
#include<bits/stdc++.h> using namespace std; #define int long long const int maxn = 1e6 + 5, N = 5e5 + 5, mod = 998244353; int qpow(int b, int p) { int res = 1; while (p) { if (p & 1) { res = res * b % mod; } b = b * b % mod; p >>= 1; } return res; } int n, k, fac[maxn], ifac[maxn], g[N]; inline void init() { fac[0] = 1; for (int i = 1; i <= N; i ++) { fac[i] = fac[i - 1] * i % mod; } ifac[N] = qpow(fac[N], mod - 2); for (int i = N - 1; ~i; i --) { ifac[i] = ifac[i + 1] * (i + 1) % mod; } } inline int C(int n, int m) { if (n < m || n < 0 || m < 0) { return 0; } else { return fac[n] * ifac[m] % mod * ifac[n - m] % mod; } } signed main() { cin >> n >> k, init(); for(int m = k; m <= n / 4; m ++) { int p = n - 4 * m; g[m] = C(p + m, m) * qpow(10, p) % mod; } int ans = 0; for(int i = n / 4; i >= k; i --) { if(i - k & 1) ans = (ans - C(i, k) * g[i] % mod + mod) % mod; else ans = (ans + C(i, k) * g[i] % mod) % mod; } cout << ans << '\n'; return 0; } -
- 1
信息
- ID
- 10696
- 时间
- 1000ms
- 内存
- 512MiB
- 难度
- 5
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者