牛客练习赛39 C 流星雨

Description:

链接:https://ac.nowcoder.com/acm/contest/368/C
来源:牛客网

现在一共有n天,第i天如果有流星雨的话,会有w_i颗流星雨。

第i天有流星雨的概率是p_i

如果第一天有流星雨了,那么第二天有流星雨的可能性是,否则是p_2。相应的,如果第天有流星雨,第i天有流星雨的可能性是,否则是p_i

求n天后,流星雨颗数的期望。

Input:

n,a,b 其中 P=a/b

wi(for i=1...n)

ai bi (for i=1...n) 其中 pi=ai/bi

Output:

答案

Analysis:

先用递推式 P[i] = P[i - 1] * (p[i] + p0)+ (1 - P[i - 1])*p[i]求出每一天的下流星雨概率,然后乘上w加和即为答案,用快速幂求逆元

#define _CRT_SECURE_NO_WARNINGS  
#include<iostream>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<sstream>
#include<cmath>
#include<iterator>
#include<bitset>
#include<stdio.h>
#include<unordered_set>
#include<ctime>
#include<cstring>
using namespace std;
#define _for(i,a,b) for(int i=(a);i<(b);++i)
#define _rep(i,a,b) for(int i=(a);i<=(b);++i)
typedef long long LL;
const int INF = 1 << 30;
const int maxn = 100005;
const int MOD = 1e9+7;
const double eps = 1e-6;

LL n,p[maxn],P[maxn],p0;
LL w[maxn];

LL pow_mod(LL a, LL b) {
	LL res = 1;
	while (b) {
		if (b & 1)res = (res*a) % MOD;
		a = (a * a)%MOD;
		b /= 2;
	}
	return res;
}

int main()
{
	//freopen("C:\\Users\\admin\\Desktop\\in.txt", "r", stdin);
	//freopen("C:\\Users\\admin\\Desktop\\out.txt", "w", stdout);
	LL a, b;
	scanf("%lld%lld%lld", &n, &a, &b);
	p0 = (a * pow_mod(b, MOD - 2))%MOD;
	_rep(i, 1, n) scanf("%lld", &w[i]);
	_rep(i, 1, n) {
		scanf("%lld%lld", &a, &b);
		p[i] = (a * pow_mod(b, MOD - 2)) % MOD;
	}
	P[1] = p[1];
	_rep(i, 2, n) {
		P[i] = ((P[i - 1] * (p[i] + p0)) % MOD + (1 - P[i - 1]+MOD)%MOD*p[i] % MOD) % MOD;
	}
	LL ans = 0;
	_rep(i, 1, n) {
		ans = (ans + w[i] * P[i] % MOD) % MOD;
	}
	cout << ans << endl;

	return 0;
}

猜你喜欢

转载自blog.csdn.net/tomandjake_/article/details/86807951