条件期望 以及 CF1172C2 Nauuo and Pictures (hard version) 题解
前言
再次看到这一题是在某带砖的思政课上。回忆中,第一次看到这题的时,我尚懵懂,并不会做。如今,将这题推给我的人已功成名就,而我却一无所有,不禁黯然神伤,感慨时移世异以至沧海桑田。兴许能把以前自己不会的题做出来,已然是莫大的安慰,故作文以记之。
首先考虑朴素的解法:
对于任何一幅图片,我只关心它被访问过多少次,以及当前的总和是多少,因此:
令
然后可以借助
不难发现这个做法中的很大一部分时间复杂度都是由于符号引起的,如果能把符号去掉就好了
然后不妨思考一个东西:
要是所有照片都是
如果所要照片都是
因此记
然后考虑一下进行第
这就很有意思了,你发现某一次访问某个照片的概率与具体访问过它几次无关,而与它当前的期望有关
而由于期望是线性的,某个照片当前的期望就是每一步访问它次数的期望之和,这个玩意儿可以写成一个递推式:
怎么创造所有照片的符号都相同这一个条件呢
那就是计算出来,在
这个可以用一个
就是
感觉这题实质上是对于条件期望以及条件概率的考察
附代码
#include <bits/stdc++.h> #define int long long using namespace std; inline int read(){ int x=0,f=1;char ch=getchar(); for(;!isdigit(ch);ch=getchar())f^=ch=='-'; for(;isdigit(ch);ch=getchar())x=x*10+(ch^48); return f?x:-x; } const int M=3005,N=2e5+5,mo=998244353; inline int qpow(int x,int t){ int ret=1; for(;t;t>>=1,x=x*x%mo)if(t&1)ret=ret*x%mo; return ret; } inline void red(int &x){x>=mo?x-=mo:0;} int n,m,sum[3],f[M][M],w[N],a[N],ans[N],inv[2][M],fact[2]; signed main(){ n=read(),m=read(); for(int i=1;i<=n;++i) a[i]=read(); for(int i=1;i<=n;++i){ w[i]=read(); sum[a[i]]+=w[i]; } sum[2]=sum[0]+sum[1]; for(int i=0;i<=m;++i)for(int t=0;t<2;++t) inv[t][i]=qpow(sum[t]+(t?i:-i),mo-2); f[0][0]=1; for(int tot=1;tot<=m;++tot){ for(int i=0,j=tot;i<=min(sum[0],tot);++i,--j){ int wtot,w; if(i>0){ wtot=sum[2]+j-i+1,w=sum[0]-(i-1); red(f[i][j]+=qpow(wtot,mo-2)*w%mo*f[i-1][j]%mo); } if(j>0){ wtot=sum[2]+j-i-1,w=sum[1]+(j-1); red(f[i][j]+=qpow(wtot,mo-2)*w%mo*f[i][j-1]%mo); } } } for(int t=0;t<2;++t){ int val=1,tag=t?1:mo-1; fact[t]=val*(t?f[m][0]:f[0][m]); for(int j=1;j<=m;++j){ val=val*(1+tag*inv[t][j-1]%mo)%mo; red(fact[t]+=val*(t?f[m-j][j]:f[j][m-j])%mo); } } for(int i=1;i<=n;++i){ printf("%lld\n",w[i]*fact[a[i]]%mo); } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效