题解:P17856 [LBA-OI R6 D] 奶龙游戏
XFrostKris · · 题解
闲话
做完题没事干,写一篇题解吧。
概率题,数据量这么大大概率不是 DP,是一个公式题。
感觉这种使用卡特兰数思想的计数问题特别少,这题差不多蓝题水平。
Solution
总方案数
考虑怎么计数恰好
通过观察,我们可以发现
下文记
继续观察:我们发现
考虑这样的一个对满足什么性质,不妨从小到大考虑
如果前面有一个数分给 Bob 了,且这个数分给了 Alice,对数
如果前面有一个数分给 Alice 了,且这个数分给了 Bob,对数
由于前面的 Alice 贡献一定会有 Bob 结算,因此,我们可以在一但有一个数就对数
所以我们的任务:
构造一个长度为
这是一个特别经典的问题,就像卡特兰数(任意前缀都在
记
做对称点然后相减即可。
答案就是:
::::success[代码]
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define rep(i,x,y) for(int i=x;i<=y;i++)
#define per(i,x,y) for(int i=x;i>=y;i--)
const int N = 2e6+5;
const int INF = 0x3f3f3f3f;
const int mod = 998244353;
int n;
int frc[N * 2], infrc[N * 2];
int ksm(int a, int b) {
a %= mod;
int res = 1;
while (b) {
if (b & 1) res = (res * a) % mod;
b >>= 1;
a = (a*a) % mod;
}
return res;
}
int C(int n, int m) {
if (n < 0 || n < m || m < 0) return 0;
return frc[n] % mod*infrc[m] % mod*infrc[n - m] % mod;
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(nullptr);
cout.tie(nullptr);
cin >> n;
frc[0] = 1;
rep(i, 1, 2 * n) frc[i] = (frc[i - 1] * i) % mod;
infrc[2 * n] = ksm(frc[2 * n], mod - 2);
per(i, 2 * n - 1, 0) infrc[i] = (infrc[i + 1] * (i + 1)) % mod;
int tot = C(2 * n, n);
int inv = ksm(tot, mod - 2);
rep(k, 0, n) {
int ans = tot;
ans -= C(2 * n, n + k + 1) + C(2 * n, k - 1);
ans = (ans % mod + mod) % mod;
ans = ans % mod*inv % mod;
cout << ans << '\n';
}
return 0;
}
::::