题干:

现在一共有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

解题报告:

dp[i]代表第i天下雨的真正概率。可知,第i天的概率只与第i-1天有关,递推方程容易求出,最后再乘以权值w[i]。最后输出模意义下的解。

AC代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<ctime>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
#define fi first
#define se second
using namespace std;
const int MAX = 2e5 + 5;
ll p[MAX],w[MAX];
ll dp[MAX];//设dp[i]为第i天下雨的真正概率,由于第i天的概率只与第i-1天有关
const ll mod = 1e9+7;
ll qpow(ll a,ll k) {
    ll res = 1;
    while(k) {
        if(k&1) res = (res*a)%mod;
        k>>=1;
        a = (a*a)%mod;
    }
    return res;
}
int main()
{
    ll n,a,b,x,y;
    cin>>n>>a>>b;
    ll P = a*qpow(b,mod-2)%mod;
    for(int i = 1; i<=n; i++) scanf("%lld",w+i);
    for(int i = 1; i<=n; i++) {
        scanf("%lld%lld",&x,&y);
        p[i] = x*qpow(y,mod-2)%mod;
    }
    for(int i = 1; i<=n; i++) {
        dp[i] = dp[i-1] * (p[i]+P) %mod;
        dp[i] += (1-dp[i-1]+mod)*p[i]%mod;
        dp[i] %= mod; 
    }
    ll ans = 0;
    for(int i = 1; i<=n; i++) {
        ans = (ans + dp[i]*w[i]%mod)%mod;
    }
    printf("%lld\n",ans);
    return 0 ;
}