题面
SOL
做法貌似挺多? (比如多项式)
一道模拟型的概率dp;
首先我们
r
e
a
d
t
h
e
p
r
o
b
l
e
m
read\ the\ problem
read the problem,然后
m
a
k
e
a
d
r
a
f
t
make\ a\ draft
make a draft,然后
A
C
AC
AC。
其实中间背包dp的可逆性挺妙的。(可能是我tcl。。)
对于操作1,维护每一回合每个点的每点生命值的概率。
对于操作2,先不管一定选某个点的情况,相当于做一个 0 / 1 0/1 0/1背包。然后我们需要得到必须选第 i i i点的 d p dp dp值。发现,无论 d p dp dp的顺序,最后的 f [ n ] [ i = 1... n ] f[n][i=1...n] f[n][i=1...n]的答案是一定的。
所以我们可以假设第 i i i个点最后选,用 f [ n ] [ n ] = f [ n − 1 ] [ n − 1 ] ∗ p i f[n][n]=f[n-1][n-1]*p_i f[n][n]=f[n−1][n−1]∗pi 逆推出 f [ n − 1 ] [ n − 1 ] ( 没 有 选 第 i 点 ) f[n-1][n-1](没有选第i点) f[n−1][n−1](没有选第i点) 然后再倒着推下去就行了。
CODE
#include<bits/stdc++.h>
using namespace std;
#define sf scanf
#define pf printf
#define ll long long
#define cs const
#define ri register int
#define db double
#define lb long double
#define gc getchar()
#define in red()
inline int red(){
int num=0,f=1;char c=gc;
for(;!isdigit(c);c=gc)if(c=='-')f=-1;
for(;isdigit(c);c=gc)num=num*10+(c^48);
return num*f;
}
cs int N=210,mod=998244353;
inline int mul(cs int &a,cs int &b){return 1ll*a*b%mod;}
inline int add(cs int &a,cs int &b){return a+b>mod ? a-mod+b:a+b;}
inline int dec(cs int &a,cs int &b){return a-b<0 ? a+mod-b : a-b;}
inline int ksm(int a,int b){int ans=1;for(;b;b>>=1,a=mul(a,a))if(b&1)ans=mul(ans,a);return ans;}
int iv[N],F[N],p[N][N],iP[N],f[N],m[N],n,Q;
vector<int>V;
inline void op1(){
int n=V.size();
for(ri i=1;i<=n;++i)f[i]=0;
f[0]=1;
for(ri id=0,i;id<n;++id){
i=V[id];
int P=dec(1,p[i][0]),dP=dec(1,P);
for(ri j=n;j>=1;--j){
f[j]=add(mul(f[j],dP),mul(f[j-1],P));
}
f[0]=mul(f[0],dP);
}
for(ri id=0,i;id<n;++id){
i=V[id];
int P=dec(1,p[i][0]),dP=dec(1,P),now=mul(iP[i],f[n]);F[i]=0;
for(ri t=n;t>=1;--t){
F[i]=add(F[i],mul(iv[t],now));
now=mul(iP[i],dec(f[t-1],mul(dP,now)));
}
F[i]=mul(F[i],P);
}
}
inline void op0(int i,int P){
int dP=dec(1,P);
p[i][0]=add(p[i][0],mul(p[i][1],P));
for(ri j=1;j<=m[i];++j){
p[i][j]=add(mul(dP,p[i][j]),mul(P,p[i][j+1]));
}
iP[i]=ksm(dec(1,p[i][0]),mod-2);
}
inline void init(){
for(ri i=1;i<=n;++i)p[i][m[i]]=1,iP[i]=1,iv[i]=ksm(i,mod-2);
}
signed main(){
// freopen("data.in","r",stdin);
n=in;
for(ri i=1;i<=n;++i)m[i]=in;
init();
Q=in;
while(Q--){
int op=in,id,u,v,k;
if(op==0)id=in,u=in,v=in,op0(id,mul(u,ksm(v,mod-2)));
if(op==1){
k=in;V.clear();
while(k--)V.push_back(in);
op1();
for(ri i=0,up=V.size();i<up;++i){
cout<<F[V[i]]<<' ';
}
cout<<'\n';
}
}
for(ri i=1;i<=n;++i){
int ans=0;
for(ri j=1;j<=m[i];++j){
ans=add(ans,mul(j,p[i][j]));
}
cout<<ans<<' ';
}
cout<<'\n';
return 0;
}