(期望概率)流星雨

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

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 131072K,其他语言262144K
64bit IO Format: %lld

题目描述

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

第i天有流星雨的概率是pipi。

如果第一天有流星雨了,那么第二天有流星雨的可能性是p2+Pp2+P,否则是p2p2。相应的,如果第i−1 (i≥2)i−1 (i≥2)天有流星雨,第i天有流星雨的可能性是pi+Ppi+P,否则是pipi。

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

输入描述:

 

第一行三个整数,n,a,b,其中n为天数,P=abP=ab

第二行n个整数wiwi。

接下来n行,每行两个整数,x,y,第i+2行表示第i天有流星雨的概率pi=xypi=xy。

1≤n≤105, 1≤a,b,x,y,wi≤109, pi+P≤1.01≤n≤105, 1≤a,b,x,y,wi≤109, pi+P≤1.0

输出描述:

 

一行一个整数,为答案对109+7109+7 取模的结果。

即设答案化为最简分式后的形式为abab,其中a和b互质。输出整数 x 使得bx≡a(mod 109+7)bx≡a(mod 109+7)且0≤x<109+70≤x<109+7。可以证明这样的整数x是唯一的。

 

示例1

输入

复制

2 1 3
1 1 
1 2
1 2

输出

复制

166666669

说明

 

第一天有流星雨第二天也有流星雨的概率是12×(12+13)12×(12+13),然后乘以流星雨的颗数2

 

第一天有流星雨第二天没有流星雨的概率是12×1612×16,乘以颗数1

第一天没有,第二天有的概率12×1212×12,乘以颗数1

第一天没有,第二天也没有的概率12×1212×12,乘以颗数0。

所以流星雨颗数的期望是7676

示例2

输入

复制

3 1 5
1 1 2
1 2
1 4
2 3

输出

复制

763333341

题解:(期望):E(X) = X1*p(X1) + X2*p(X2) + …… + Xn*p(Xn)

             我们只需要求出每个p(Xi)就可以了,p(Xi) =  p(Xi-1)*(g(Xi)+P)+(1 - p*(Xi-1))*g(Xi) = g(Xi) + p(Xi-1)*P

#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<bitset>
#include<iomanip>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#define eps (1e-8)
#define MAX 0x3f3f3f3f
#define u_max 1844674407370955161
#define l_max 9223372036854775807
#define i_max 2147483647
#define re register
#define pushup() tree[rt]=max(tree[rt<<1],tree[rt<<1|1])
#define nth(k,n) nth_element(a,a+k,a+n);  // 将 第K大的放在k位
#define ko() for(int i=2;i<=n;i++) s=(s+k)%i // 约瑟夫
#define ok() v.erase(unique(v.begin(),v.end()),v.end()) // 排序,离散化
using namespace std;

inline int read(){
    char c = getchar(); int x = 0, f = 1;
    while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
    while(c >= '0' & c <= '9') x = x * 10 + c - '0', c = getchar();
    return x * f;
}

typedef long long ll;
const double pi = atan(1.)*4.;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3fLL;
const int M=63;
const int N=1e5+5;
ll mod=1e9+7;
int w[N];
int x[N],y[N];
ll dp[N];
ll po_w(ll a,ll b){
    ll ans=1;
    while(b){
        if(b&1)
            ans=ans*a%mod;
        b>>=1;
        a=a*a%mod;
    }
    return ans;
}
int main(){
    int n,a,b;

    scanf("%d %d %d",&n,&a,&b);
    ll P=a*po_w(b,mod-2)%mod;
    for(int i=1;i<=n;i++)
        scanf("%d",&w[i]);
    for(int i=1;i<=n;i++)
        scanf("%d %d",&x[i],&y[i]);
    dp[1]=x[1]*po_w(y[1],mod-2)%mod;
    for(int i=2;i<=n;i++){
        dp[i]=(dp[i-1]%mod*P)%mod+x[i]*po_w(y[i],mod-2)%mod;
        dp[i]%=mod;
    }
    ll ans=0;
    for(int i=1;i<=n;i++){
        ans=(ans+dp[i]*w[i])%mod;
    }
    printf("%lld\n",ans);
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值