[生成函数]2021牛客第四场 B Sample Game

题目

有一个随机数生成器,每次生成 i i i的概率为 p i p_i pi,如果现在生成的数不小于之前生成的所有数,继续随机,反之,记上分数为 n 2 n^2 n2, n n n为已经生成的数的个数

思路

设最长答案长度是 l e n len len,
设生成函数,设它的系数是 l e n > i len>i len>i的概率 P ( l e n > i ) P(len>i) P(len>i),得: f ( x ) = ∑ i = 0 ∞ P ( l e n > i ) x i f(x)=\sum_{i=0}^{\infin}P(len>i)x^i f(x)=i=0P(len>i)xi

对于一种情况,设第 i i i个不同的数出现过 c n t i cnt_i cnti次,那么该种情况的概率为: ∏ i = 1 n p i c n t i \prod_{i=1}^{n}p_i^{cnt_i} i=1npicnti

所以我们可以枚举每一个数可能出现的次数,它的生成函数为:
g i ( x ) = ∑ j = 0 ∞ p i j x j = 1 1 − p i x g_i(x)=\sum_{j=0}^{\infin}p_i^jx^j=\frac{1}{1-p_ix} gi(x)=j=0pijxj=1pix1

把所有可能的次数乘起来,每一个结果都对应不同的情况:
f ( x ) = ∏ i = 1 n g i ( x ) f(x)=\prod_{i=1}^{n}g_i(x) f(x)=i=1ngi(x)
带入上方公式: f ( x ) = ∏ i = 1 n 1 1 − p i x f(x)=\prod_{i=1}^{n}\frac{1}{1-p_ix} f(x)=i=1n1pix1

长度等于 i i i时的概率 P ( l e n = i ) = P ( l e n > i − 1 ) − P ( l e n > i ) P(len=i)=P(len>i-1)-P(len>i) P(len=i)=P(len>i1)P(len>i)
答案 E ( l e n = i ) = P ( l e n = i ) ∗ i 2 E(len=i)=P(len=i)*i^2 Elen=i=P(len=i)i2
所有答案为:
∑ i = 1 ∞ ( P ( l e n > i − 1 ) − P ( l e n > i ) ) ∗ i 2 \sum_{i=1}^{\infin}(P(len>i-1)-P(len>i))*i^2 i=1(P(len>i1)P(len>i))i2
= . . . + P ( l e n > i − 1 ) i 2 − P ( l e n > i ) i 2 + P ( l e n > i ) ∗ ( i + 1 ) 2 − P ( l e n > i + 1 ) ( i + 1 ) 2 + . . . =...+P(len>i-1)i^2-P(len>i)i^2+P(len>i)*(i+1)^2-P(len>i+1)(i+1)^2+... =...+P(len>i1)i2P(len>i)i2+P(len>i)(i+1)2P(len>i+1)(i+1)2+...
= ∑ i = 0 ∞ ( P ( l e n > i ) ) ∗ ( ( i + 1 ) 2 − i 2 ) =\sum_{i=0}^{\infin}(P(len>i))*((i+1)^2-i^2) =i=0(P(len>i))((i+1)2i2)
( 看 到 有 地 方 再 说 P ( l e n > 0 ) 的 时 候 的 问 题 , i = 0 的 时 候 也 满 足 这 个 式 子 ) (看到有地方再说P(len>0)的时候的问题,i=0的时候也满足这个式子) Plen>0i=0
= ∑ i = 0 ∞ ( P ( l e n > i ) ) ∗ ( 2 i + 1 ) =\sum_{i=0}^{\infin}(P(len>i))*(2i+1) =i=0(P(len>i))(2i+1)

f ( x ) = ∑ i = 1 ∞ P ( l e n > i ) x i f(x)=\sum_{i=1}^{\infin}P(len>i)x^i f(x)=i=1P(len>i)xi
f ′ ( x ) = i ∗ ∑ i = 1 ∞ P ( l e n > i ) x i − 1 f'(x)=i*\sum_{i=1}^{\infin}P(len>i)x^{i-1} f(x)=ii=1P(len>i)xi1
f ( 1 ) = ∑ i = 1 ∞ P ( l e n > i ) f(1)=\sum_{i=1}^{\infin}P(len>i) f(1)=i=1P(len>i)
f ′ ( 1 ) = i ∗ ∑ i = 1 ∞ P ( l e n > i ) f'(1)=i*\sum_{i=1}^{\infin}P(len>i) f(1)=ii=1P(len>i)

∑ i = 1 ∞ ( P ( l e n > i − 1 ) − P ( l e n > i ) ) ∗ i 2 \sum_{i=1}^{\infin}(P(len>i-1)-P(len>i))*i^2 i=1(P(len>i1)P(len>i))i2
= . . . + P ( l e n > i − 1 ) i 2 − P ( l e n > i ) i 2 + P ( l e n > i ) ∗ ( i + 1 ) 2 − P ( l e n > i + 1 ) ( i + 1 ) 2 + . . . =...+P(len>i-1)i^2-P(len>i)i^2+P(len>i)*(i+1)^2-P(len>i+1)(i+1)^2+... =...+P(len>i1)i2P(len>i)i2+P(len>i)(i+1)2P(len>i+1)(i+1)2+...

代入原式子: ∑ i = 1 ∞ ( P ( l e n > i ) ) ∗ ( 2 i + 1 ) = 2 ∗ f ′ ( 1 ) + f ( 1 ) \sum_{i=1}^{\infin}(P(len>i))*(2i+1)=2*f'(1)+f(1) i=1(P(len>i))(2i+1)=2f(1)+f(1)

f ( 1 ) = ∏ i = 1 n 1 1 − p i f(1)=\prod_{i=1}^{n}\frac{1}{1-p_i} f(1)=i=1n1pi1
f ′ ( x ) = f ( x ) ∑ i = 1 n p i 1 − p i x f'(x)=f(x)\sum_{i=1}^{n}\frac{p_i}{1-p_ix} f(x)=f(x)i=1n1pixpi
f ′ ( 1 ) = f ( 1 ) ∑ i = 1 n p i 1 − p i f'(1)=f(1)\sum_{i=1}^{n}\frac{p_i}{1-p_i} f(1)=f(1)i=1n1pipi

代码

#include <bits/stdc++.h>
#define int long long
using namespace std;
typedef long long ll;
int w[1000],p[1000];
const int mod =998244353;
int quick_pow(int a,int b){
	int res=1;
	while(b){
		if(b&1) res=res*a%mod;
		b>>=1;
		a=a*a%mod;
	}
	return res;
}
signed main(){
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int n;
    cin>>n;
    int ans=0;
    for(int i=1;i<=n;i++){
    	cin>>w[i];
    	ans+=w[i];
	}
	int inv=quick_pow(ans,mod-2)%mod;
	int pp=0,f1=1;
	for(int i=1;i<=n;i++){
		p[i]=w[i]*inv%mod;
		f1=(f1*quick_pow((1-p[i]+mod),mod-2))%mod;
		
		pp=(pp+p[i]*quick_pow(1-p[i]+mod,mod-2)%mod)%mod;
	}
	

	cout<<(f1+2*f1*pp%mod)%mod<<endl;
    return 0;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值