题目链接
题目大意
有一个可以生成
1
1
1到
n
(
1
≤
n
≤
100
)
n(1 \leq n \leq 100)
n(1≤n≤100)的随机数生成器,生成
x
(
1
≤
x
≤
n
)
x(1 \leq x \leq n)
x(1≤x≤n)的概率为
p
x
p_x
px。
输入
W
i
W_i
Wi,
p
i
p_i
pi的计算公式为
w
i
∑
j
=
1
n
W
j
\frac{w_i}{\sum^n_{j=1}W_j}
∑j=1nWjwi.
现在一次执行以下操作:
1.随机生成一个数
x
x
x;
2.若
x
x
x是之前生成的数中最大的,则执行步骤1,否则执行步骤3;
3.若共生成了
y
y
y个数字,则得到分数
y
2
y^2
y2;
求获得分数的期望值。
题解
易得
x
x
x的期望为
f
x
=
1
×
∑
i
=
1
x
−
1
p
i
+
p
x
(
1
+
f
x
)
+
∑
i
=
x
+
1
n
p
i
(
1
+
f
i
)
f_x=1 \times \sum^{x-1}_{i=1}p_i+p_x(1+f_x)+\sum^{n}_{i=x+1}p_i(1+f_i)
fx=1×i=1∑x−1pi+px(1+fx)+i=x+1∑npi(1+fi)
经化简得
f
x
=
1
+
∑
i
=
x
+
1
n
p
i
f
i
1
−
p
x
f_x=\frac{1+\sum\limits^{n}_{i=x+1}p_if_i}{1-p_x}
fx=1−px1+i=x+1∑npifi
由于
f
(
x
2
)
!
=
f
(
x
)
2
f(x^2)!=f(x)^2
f(x2)!=f(x)2,所以无法直接得到结果,但
f
(
x
+
1
)
2
=
f
(
x
)
2
+
2
f
(
x
)
+
1
f(x+1)^2=f(x)^2+2f(x)+1
f(x+1)2=f(x)2+2f(x)+1,所以我们可以用一个新的
d
p
dp
dp数组来储存
f
(
x
)
2
f(x)^2
f(x)2.
易得
d
p
x
=
1
×
∑
i
=
1
x
−
1
p
i
+
p
x
(
1
+
2
×
f
x
+
d
p
x
)
+
∑
i
=
x
+
1
n
p
i
(
1
+
2
×
f
i
+
d
p
i
)
dp_x=1 \times \sum^{x-1}_{i=1}p_i+p_x(1+2 \times f_x +dp_x)+\sum^{n}_{i=x+1}p_i(1+2 \times f_i+dp_i)
dpx=1×i=1∑x−1pi+px(1+2×fx+dpx)+i=x+1∑npi(1+2×fi+dpi)
经化简得
d
p
x
=
1
+
2
p
x
f
x
+
∑
i
=
x
+
1
n
p
i
(
d
p
i
+
2
×
f
i
)
1
−
p
x
dp_x=\frac{1+2p_xf_x +\sum\limits^{n}_{i=x+1}p_i(dp_i+2 \times f_i)}{1-p_x}
dpx=1−px1+2pxfx+i=x+1∑npi(dpi+2×fi)
然后统计其中
d
p
i
+
2
∗
f
i
+
1
dp_i+2*f_i+1
dpi+2∗fi+1的总值
经化简得
a
n
s
=
1
+
∑
i
=
1
n
p
i
(
d
p
i
+
2
×
f
i
)
;
ans=1+\sum^{n}_{i=1}p_i(dp_i+2 \times f_i);
ans=1+i=1∑npi(dpi+2×fi);
注意结果全程要取余
m
o
d
=
998244353
mod=998244353
mod=998244353,还要采用费马小定理即快速幂来取余(超范围的全给他模上【狗头】)。
参考代码
#include<bits/stdc++.h>
#define ll long long
const ll mod=998244353;
const int N=1e2+5;
ll dp[N],f[N],w[N],p[N],sum[N],num[N];
ll n,s;
ll pow(ll a,ll b)
{
ll ret=1;
while(b)
{
if(b&1)
ret=ret*a%mod;
a=a*a%mod;
b>>=1;
}
return ret;
}
int main()
{
scanf("%lld",&n);
for(int i=1;i<=n;i++)
{
scanf("%lld",&w[i]);
s+=w[i];
}
for(int i=1;i<=n;i++)
p[i]=pow(s,mod-2)*w[i]%mod;
num[n]=0;
for(int i=n;i>=1;i--)
{
f[i]=(1+num[i])*pow((1+mod-p[i]),mod-2)%mod;
num[i-1]=(f[i]*p[i]%mod+num[i])%mod;
}
num[n]=0;
for(int i=n;i>=1;i--)
{
dp[i]=(1+2*f[i]*p[i]%mod+num[i])*pow((1+mod-p[i]),mod-2)%mod;
num[i-1]=(p[i]*(dp[i]+2*f[i])+num[i])%mod;
}
printf("%lld\n",(num[0]+1)%mod);
}