牛客等级之题N1(8.3) (数论递推通项公式)

链接:https://ac.nowcoder.com/acm/contest/6766/A

题目描述

有一个箱子,开始时有n个黑球,m个蓝球。每一轮游戏规则如下:
第一步:奕奕有p的概率往箱子里添加一个黑球,有(1-p)的概率往箱子里添加一个蓝球。
第二步:华华随机从箱子里取出一个球。
华华喜欢黑球,他想知道k轮游戏之后箱子里黑球个数的期望。

输入描述:

输入五个整数n,m,k,a,b。
1<=n,m<=1e6,1<=k<=1e9
其中p=ab\frac{a}{b}ba,且a<=b,0<=a<1e9+7,0<b<1e9+7

输出描述:

输出一个数表示k轮游戏后箱子里黑球个数的期望。
输出一个整数,为答案对1e9+7取模的结果。即设答案化为最简分式后的形式为ab\frac{a}{b}ba,其中a和b互质。输出整数 x 使得bx≡a(mod 1e9+7)且0≤x<1e9+7。可以证明这样的整数x是唯一的。
示例

输入

2 2 1 1 2

输出

2

输入

2 2 2 3 10

输出

184000003

 

题解:

关于这个题首先要抓住一个重点,就是每一轮过后,期望就会发现变化,即:

相邻两轮游戏后的期望值是有一个递推关系的

假设第k轮后黑球数量的期望是a[k]

只要先找到a[k]与a[k+1]的关系,然后通过递推关系找到a[k]的通项公式,并把a[k]的通项公式表示为分数的形式,然后利用分数取模找逆元,就可以得到答案。

参考链接:https://blog.csdn.net/weixin_43702895/article/details/90343536#commentBox

#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn=5e5+7;
const ll mod =1e9+7;

ll mul(ll a, ll b){//防止溢出
    ll ans = 0;
    while (b){
        if(b & 1){
            ans = (ans+a)%mod;
        }
        a = (a+a)%mod;
        b = b>>1;
    }
    return ans;
}
ll quickpow(ll a, ll b){
    ll ans = 1, base = a%mod;
    while (b){
        if(b & 1){
            ans = mul(ans, base)%mod;
        }
        base = mul(base, base)%mod;
        b = b>>1;
    }
    return ans;
}

int main(){
    ll n,m,k,a,b;
    scanf("%lld%lld%lld%lld%lld",&n,&m,&k,&a,&b);
    //cout<<n<<" "<<m<<" "<<k<<" "<<a<<" "<<b<<endl; 
    ll pa=quickpow(n+m+1,k);
    ll pb=quickpow(n+m,k);
    ll fa=( (b*n%mod-a*n%mod-a*m%mod)*pb%mod +((a*(n+m)%mod)%mod*pa) %mod)%mod;    
    ll fb=b*pa%mod;
    ll inv=quickpow(fb,mod-2);
    printf("%lld\n",(fa*inv%mod+mod)%mod);

    
    return 0;
}
View Code

 

posted @ 2020-08-03 22:55  杰瑞与汤姆  阅读(283)  评论(0编辑  收藏  举报