# 【BZOJ5340】假面（CTSC2018）-概率DP

$an{s}_{i}=\sum _{j=0}^{k-1}\frac{1}{j+1}g\left(i,j\right)$

$f\left(i,j\right)={p}_{i}f\left(i-1,j-1\right)+\left(1-{p}_{i}\right)f\left(i-1,j\right)$

$f\left(k-1,j\right)=\frac{f\left(k,j\right)-{p}_{k}f\left(k-1,j-1\right)}{1-{p}_{k}}$

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=998244353;
int n,m[210],q,pos[210];
ll inv[210]={0},t[210][110]={0},f[210][210]={0},g[210]={0};

ll power(ll a,ll b)
{
ll s=1,ss=a;
while(b)
{
if (b&1) s=s*ss%mod;
ss=ss*ss%mod;b>>=1;
}
return s;
}

int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&m[i]);
t[i][m[i]]=1;
inv[i]=power(i,mod-2);
}

scanf("%d",&q);
for(int i=1;i<=q;i++)
{
int op,id,k;
ll u,v;
scanf("%d",&op);
if (!op)
{
scanf("%d%lld%lld",&id,&u,&v);
ll p=u*power(v,mod-2)%mod;
t[id][0]=(t[id][0]+p*t[id][1])%mod;
for(int j=1;j<=m[id];j++)
t[id][j]=(((1ll-p)*t[id][j]+p*t[id][j+1])%mod+mod)%mod;
}
else
{
scanf("%d",&k);
f[0][0]=1;
for(int j=1;j<=k;j++)
{
scanf("%d",&pos[j]);
f[j][0]=f[j-1][0]*t[pos[j]][0]%mod;
for(int p=1;p<=j;p++)
f[j][p]=((f[j-1][p]*t[pos[j]][0]+f[j-1][p-1]*(1ll-t[pos[j]][0]))%mod+mod)%mod;
}
for(int j=1;j<=k;j++)
{
ll ans=0;
if (t[pos[j]][0])
{
ll nowinv=power(t[pos[j]][0],mod-2);
g[0]=f[k][0]*nowinv%mod;
for(int p=1;p<k;p++)
g[p]=((f[k][p]-g[p-1]*(1ll-t[pos[j]][0]))%mod+mod)%mod*nowinv%mod;
}
else
{
for(int p=0;p<k;p++)
g[p]=f[k][p+1];
}
for(int p=0;p<k;p++)
ans=(ans+inv[p+1]*g[p])%mod;
printf("%lld ",(ans*(1ll-t[pos[j]][0])%mod+mod)%mod);
}
printf("\n");
}
}

for(int i=1;i<=n;i++)
{
ll ans=0;
for(ll j=1;j<=m[i];j++)
ans=(ans+j*t[i][j])%mod;
printf("%lld ",ans);
}

return 0;
}
posted @ 2018-05-21 16:27  Maxwei_wzj  阅读(108)  评论(0编辑  收藏  举报