CF1392H ZS Shuffles Cards 题解
题目链接
题目解法
很牛逼的概率题,参考了题解区
定义取到鬼牌,重新洗牌,为一轮
则 轮数这一轮取到鬼牌的期望步数,轮数为在 之前取到鬼牌的次数
先计算 这一轮取到鬼牌的期望步数,这是比较好算的
考虑期望的线性性,即换角度考虑问题,我们假设会取完所有的牌,但第一次出现的鬼牌之后的牌不算步数,所以对于每个数字牌,前面没有鬼牌的概率显然为 ,所以取到鬼牌的期望次数为
再计算 轮数,这个也不太难算
取到在集合 中的数字牌对于答案是没有影响的,所以直接忽略
考虑当前剩余 张数字牌不在集合内,变到 张牌的期望轮数
在 张鬼牌, 张数字牌中抽到数字牌的期望次数为 ,因为抽到数字牌不算轮数,所以期望轮数为
所以 轮数 即为
总结一下,答案为
时间复杂度
个人感觉,这道题的难点在于想到定义轮数,即转化为 个期望次数,剩下的就比较套路
#include <bits/stdc++.h> #define F(i,x,y) for(int i=(x);i<=(y);i++) #define DF(i,x,y) for(int i=(x);i>=(y);i--) #define ms(x,y) memset(x,y,sizeof(x)) #define SZ(x) (int)x.size()-1 #define pb push_back using namespace std; typedef long long LL; typedef unsigned long long ull; typedef pair<int,int> pii; template<typename T> void chkmax(T &x,T y){ x=max(x,y);} template<typename T> void chkmin(T &x,T y){ x=min(x,y);} inline int read(){ int FF=0,RR=1; char ch=getchar(); for(;!isdigit(ch);ch=getchar()) if(ch=='-') RR=-1; for(;isdigit(ch);ch=getchar()) FF=(FF<<1)+(FF<<3)+ch-48; return FF*RR; } const int P=998244353,N=2000100; int n,m,inv[N]; int qmi(int a,int b){ int res=1; for(;b;b>>=1){ if(b&1) res=1ll*res*a%P;a=1ll*a*a%P;} return res; } int main(){ n=read(),m=read(); inv[1]=1; F(i,2,n) inv[i]=1ll*inv[P%i]*(P-P/i)%P; int res=0; F(i,1,n) res=(res+1ll*m*inv[i])%P; int ans=(1ll*n*qmi(m+1,P-2)+1)%P*(res+1)%P; printf("%d\n",ans); return 0; }
标签:
Codeforces
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现