ZS Shuffles Cards 题解
1.P5192 Zoj3229 Shoot the Bullet|东方文花帖|【模板】有源汇上下界最大流2.Phi的反函数3.魔力屏障 (magic) 题解4.CF338D GCD Table 题解5.[AGC055B] ABC Supremacy 题解6.[AGC055A] ABC Identity 题解7.QOJ 6504. CCPC Final 2022 D Flower's Land 2题解8.[SDOI2010] 代码拍卖会 题解9.PERIODNI - Periodni 题解 & 笛卡尔树讲解 & 树状背包讲解10.Burnside 定理
11.ZS Shuffles Cards 题解
ZS Shuffles Cards 题解
我们把每一次抽一些数字牌再抽到 joker 视作一局游戏。
每局期望轮数
首先考虑
那么就是先抽出
概率就是 :
一局游戏期望抽牌(轮)数量也就是:
直接算这个式子会超时,我们可以先预处理后面的部分:
令
可得
就转化成
期望局数
令
显然答案就是
若抽到了缺少的牌,那么就是:
若抽到鬼牌,那么就是(加 1 是因为新的一局):
所以就是:
化简得:
初始
因为即使你的集合内的数已经凑够了,你也要抽到 joker 才能停止。
最后答案就是
温馨提示
建议预处理逆元(我最开始没有预处理虽然本地没超时但测评会T)
code
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int mod = 998244353;
const int N = 4e6 + 10;
ll n, m, w[N], ans1 = 0, ans2 = 0;
ll pr[N], ip[N], rv[N];
inline ll mpow(ll x, ll k){
ll ans = 1;
while(k){
if(k & 1) ans = ans * x % mod;
k >>= 1;
x = x * x % mod;
}
return ans;
}
void pre(int n){
pr[0] = 1;
for(int i = 1; i <= n; ++i) pr[i] = pr[i - 1] * i % mod;
ip[n] = mpow(pr[n], mod - 2);
for(int i = n - 1; i >= 1; --i) ip[i] = ip[i + 1] * (i + 1) % mod;
for(int i = 1; i <= n; ++i) rv[i] = ip[i] * pr[i - 1] % mod;
}
void op(){
w[1] = 1;
for(int i = 1; i <= n + 1; ++i){
w[i + 1] = w[i] * (n - i + 1) % mod * rv[n + m - i + 1] % mod;
ans1 = (ans1 + i * m % mod * rv[n + m - i + 1] % mod * w[i] % mod) % mod;
}
ans2 = m + 1;
for(int i = 2; i <= n; ++i){
ans2 = (ans2 + m * rv[i] % mod) % mod;
}
}
int main(){
cin>> n >> m;
pre(n + m + 1);
op();
cout<<ans1 * ans2 % mod;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!