成功用这道题生成函数入门了
题目描述
生成 i ∈ [ 1 , n ] i \in [1,n] i∈[1,n]的数字的概率分别为 p i p_i pi
按照以下方式生成数字序列 a i a_i ai
- 生成数字 x x x
- 判断数字 x x x是否为 a i a_i ai中的最大值, 如果是则重复1, 否则停止
通过以上方式生成一共 l e n len len个数, 则得分为 l e n 2 len^2 len2
求得分的期望
其中 p i p_i pi以 w i ∑ 1 n w i \frac{w_i}{\sum_1^nw_i} ∑1nwiwi的形式给出
输出概率对
998244353
998244353
998244353取模
0
≤
w
i
≤
1
0
6
2
≤
n
≤
100
\\0\leq w_i \leq 10^6 \\2\leq n \leq 100
0≤wi≤1062≤n≤100
题目分析
一个没有结束的数字序列一定是单调不降的, 比如 1 , 1 , 1 , 2 , 2 , 3 1,1,1,2,2,3 1,1,1,2,2,3
如果一个序列的长度 l e n len len超过 i i i时对应的生成概率为 p ( l e n > i ) p(len>i) p(len>i),那么就可以知道这个序列下一个数停止的概率为 p ( l e n > i ) − p ( l e n > i + 1 ) p(len>i) - p(len>i+1) p(len>i)−p(len>i+1),那么再乘上 ( i + 1 ) 2 (i+1)^2 (i+1)2就得到了 i + 1 i+1 i+1长度的得分期望
那么求 ∑ 0 ∞ [ p ( l e n > i ) − p ( l e n > i + 1 ) ] ( i + 1 ) 2 \sum_0^\infty [p(len>i) - p(len >i+1)](i+1)^2 0∑∞[p(len>i)−p(len>i+1)](i+1)2就得到了总的期望
对这个式子进行一下化简
∑
0
∞
[
p
(
l
e
n
>
i
)
−
p
(
l
e
n
>
i
+
1
)
]
(
i
+
1
)
2
=
∑
0
∞
[
p
(
l
e
n
>
i
)
(
i
+
1
)
2
−
p
(
l
e
n
>
i
+
1
)
(
i
+
1
)
2
]
=
p
(
l
e
n
>
0
)
(
0
+
1
)
2
+
∑
1
∞
p
(
l
e
n
>
i
)
[
(
i
+
1
)
2
−
i
2
]
−
p
(
l
e
n
>
∞
)
(
∞
+
1
)
2
=
p
(
l
e
n
>
0
)
(
0
+
1
)
2
+
∑
1
∞
p
(
l
e
n
>
i
)
[
(
i
+
1
)
2
−
i
2
]
=
∑
0
∞
p
(
l
e
n
>
i
)
[
(
i
+
1
)
2
−
i
2
]
=
∑
0
∞
p
(
l
e
n
>
i
)
(
2
i
+
1
)
\sum_0^\infty[p(len > i) - p(len > i + 1)](i + 1)^2\\ = \sum_0^\infty [p(len>i)(i+1)^2 - p(len > i+1)(i+1)^2]\\ =p(len > 0)(0+1)^2 + \sum_1^\infty p(len>i)[(i+1)^2 - i^2] - p(len >\infty)(\infty + 1)^2\\ =p(len>0)(0+1)^2 + \sum_1^\infty p(len>i)[(i+1)^2 - i^2]\\ =\sum_0^\infty p(len>i)[(i+1)^2 - i^2]\\ =\sum_0^\infty p(len>i)(2i+1)
0∑∞[p(len>i)−p(len>i+1)](i+1)2=0∑∞[p(len>i)(i+1)2−p(len>i+1)(i+1)2]=p(len>0)(0+1)2+1∑∞p(len>i)[(i+1)2−i2]−p(len>∞)(∞+1)2=p(len>0)(0+1)2+1∑∞p(len>i)[(i+1)2−i2]=0∑∞p(len>i)[(i+1)2−i2]=0∑∞p(len>i)(2i+1)
那么如何求 p ( l e n > i ) p(len>i) p(len>i)呢
构造一个生成函数 g i ( x ) = ∑ k = 0 ∞ p i x k = 1 1 − p I x g_i(x) =\sum_{k=0}^{\infty}p_ix^k = \frac{1}{1-p_Ix} gi(x)=∑k=0∞pixk=1−pIx1的系数来表示对于第 i i i个数生成了 k k k次的生成概率,那么可以知道, 生成所有序列的生成函数,就是 f ( x ) = ∏ i = 1 n g i ( x ) f(x) = \prod_{i=1}^{n}g_i(x) f(x)=∏i=1ngi(x) 其中 f ( x ) f(x) f(x)的 x i x^{i} xi的系数表示未结束的序列长度为 i i i的概率, 因为生成的序列长度已经为 i i i了,所以这个序列长度最终至少为 i + 1 i+1 i+1,因此这个系数就是 p ( l e n > i ) p(len>i) p(len>i)
因此 f ( x ) = ∑ 0 ∞ p ( l e n > i ) x i = ∏ i = 1 n 1 1 − p i x f(x)=\sum_0^\infty p(len>i)x^i = \prod_{i=1}^n\frac{1}{1-p_ix} f(x)=0∑∞p(len>i)xi=i=1∏n1−pix1
f ′ ( x ) = ∑ 0 ∞ i ∗ p ( l e n > i ) x i − 1 = f ( x ) ∗ ( ∑ 0 n p i 1 − p i x ) f'(x) = \sum_0^\infty i*p(len>i)x^{i-1} = f(x)*(\sum_0^n\frac{p_i}{1-p_ix} ) f′(x)=0∑∞i∗p(len>i)xi−1=f(x)∗(0∑n1−pixpi)(复合函数的求导)
将
f
(
x
)
,
f
′
(
x
)
f(x),f'(x)
f(x),f′(x)代入原式
∑
0
∞
p
(
l
e
n
>
i
)
(
2
i
+
1
)
=
2
∗
∑
0
∞
i
∗
p
(
l
e
n
>
i
)
+
∑
0
∞
p
(
l
e
n
>
i
)
=
2
∗
f
′
(
1
)
+
f
(
1
)
\sum_0^\infty p(len>i)(2i+1) \\=2*\sum_0^\infty i*p(len>i) + \sum_0^\infty p(len>i) \\=2*f'(1)+f(1)
0∑∞p(len>i)(2i+1)=2∗0∑∞i∗p(len>i)+0∑∞p(len>i)=2∗f′(1)+f(1)
这样就可以计算啦
复杂度是 O ( n ) O(n) O(n)
所以也许可以把n再扩大一些
题目踩坑
不管算多少步,每一步都要取模, 不要因为嫌麻烦在某一步不取模!
不知道什么时候就爆long long了
记得模意义下的除法是逆元,可以使用费马小定理
AC代码
代码丑陋,仅供参考
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int MAXN = 100;
const int MOD = 998244353;
typedef long long ll;
ll qp(ll a, int b)
{
ll ans = 1;
while(b)
{
if(b & 1)
{
ans = (ans * a) % MOD;
}
b >>= 1;
a = (a * a) % MOD;
}
return ans;
}
ll inv(ll a)
{
return qp(a, MOD - 2);
}
int wi[MAXN + 100];
int main()
{
int n;
ll sum = 0;
scanf("%d", &n);
for(int i = 1; i <= n; ++i)
{
scanf("%d", &wi[i]);
sum += wi[i];
}
sum %= MOD;
ll f1 = 1;
ll df1 = 0;
for(int i = 1; i <= n; ++i)
{
ll swi = ((sum - wi[i])%MOD + MOD) % MOD;
f1 *= (sum * inv(swi)) % MOD;
f1 %= MOD;
df1 += (wi[i] * inv(swi)) % MOD;
df1 %= MOD;
}
df1 *= f1;
df1 %= MOD;
ll totans = ((df1 + df1) % MOD + f1) % MOD;
printf("%lld", totans);
return 0;
}