题目
大意就是喝汽水,每种汽水的中奖概率为
P
i
P_i
Pi,而中了序号大的汽水后不能中序号小的汽水,求喝到汽水的期望数。
分析
先看题目发现有分数和模。费马小定理(快速幂)先打好。
ll fx(ll x,ll y)
{
ll xx=1;
while(y)
{
if (y&1) xx=xx*x%mod;
x=x*x%mod;
y=y>>1;
}
return xx;
}
然后分析题目
要我们求期望的平方,我们可以先单求期望。
我们设现在选了
x
x
x,之后还能选的期望
f
x
f_x
fx。
那么可以列如下方程。
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*\sum_{i=1}^{x-1}P_i+P_x(1+f_x)+\sum_{i=x+1}^{n}P_i(1+f_i)
fx=1∗∑i=1x−1Pi+Px(1+fx)+∑i=x+1nPi(1+fi)
=
>
=>
=>
(
1
−
P
x
)
f
x
=
1
+
∑
i
=
x
+
1
n
P
i
f
i
(1-P_x)f_x=1+\sum_{i=x+1}^{n}P_if_i
(1−Px)fx=1+∑i=x+1nPifi
=
>
=>
=>
f
x
=
1
+
∑
i
=
x
+
1
n
P
i
f
i
1
−
P
x
f_x=\frac{1+\sum_{i=x+1}^{n}P_if_i}{1-P_x}
fx=1−Px1+∑i=x+1nPifi
接下来就要求期望的平方。但它不是简单的
f
x
2
f_x^2
fx2。那我们设期望的平方为
g
x
g_x
gx,那么可得:
g
x
=
1
+
2
P
x
f
x
+
∑
i
=
1
n
P
i
(
g
i
+
2
f
i
)
1
−
P
x
g_x=\frac{1+2P_xf_x+\sum_{i=1}^{n}P_i(g_i+2f_i)}{1-P_x}
gx=1−Px1+2Pxfx+∑i=1nPi(gi+2fi)
然后就可以求得答案:
a
n
s
=
1
+
∑
i
=
1
n
P
i
(
g
i
+
2
f
i
)
ans=1+\sum_{i=1}^nPi(g_i+2f_i)
ans=1+∑i=1nPi(gi+2fi)
最后再看一眼式子,可以发现,在求
g
x
g_x
gx过程中的
∑
i
=
1
n
P
i
(
g
i
+
2
f
i
)
=
a
n
s
−
1
\sum_{i=1}^{n}P_i(g_i+2f_i)=ans-1
∑i=1nPi(gi+2fi)=ans−1
那么在求的时候,用
G
G
G记录一下即可。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n,w[10010],ans,f[10010],g[10010],p[10010],W,F,G;
const ll mod=998244353;
ll fx(ll x,ll y)
{
ll xx=1;
while(y)
{
if (y&1) xx=xx*x%mod;
x=x*x%mod;
y=y>>1;
}
return xx;
}
int main()
{
scanf("%lld",&n);
for (ll i=1;i<=n;i++) scanf("%lld",w+i),W+=w[i];
for (ll i=1;i<=n;i++) p[i]=w[i]*fx(W,mod-2)%mod;
f[n]=fx(1+mod-p[n],mod-2)%mod;
F=f[n]*p[n]%mod;
g[n]=(1+2*f[n]*p[n]%mod)%mod*fx(1+mod-p[n],mod-2)%mod;
G=p[n]*(g[n]+2*f[n])%mod;
for (ll i=n-1;i>=1;i--)
{
f[i]=(F+1)*fx(1+mod-p[i],mod-2)%mod;
F=(F+f[i]*p[i])%mod;
}
for (ll i=n-1;i>=1;i--)
{
g[i]=(1+2*f[i]*p[i]+G)%mod*fx(1+mod-p[i],mod-2)%mod;
G=(G+(g[i]+2*f[i])%mod*p[i]%mod)%mod;
}
printf("%lld\n",(G+1)%mod);
}