当前位置: 首页 > 工具软件 > bcoin > 使用案例 >

Coin (2017 ACM-ICPC 亚洲区(西安赛区)网络赛B题)

后星河
2023-12-01

Bob has a not even coin, every time he tosses the coin, the probability that the coin's front face up is q/p(q/p<=1/2)。The question is, when Bob tosses the coin kk times, what's the probability that the frequency of the coin facing up is even number.If the answer is x/y, because the answer could be extremely large, you only need to print (x/y)mod(1e9+7)。


Input Format
First line an integer TT, indicates the number of test cases,Then Each line has 3 integer p,q,k(1=<p,q,k<=1e7), indicates the i-th test case.


Output Format
For each test case, print an integer in a single line indicates the answer.


样例输入
2
2 1 1
3 1 2


样例输出
500000004
555555560

题意:你掷k次一个不均匀的硬币,让你求正面朝上的频率是偶数的概率,并将结果mod 1e9+7输出。

分析:很显然,只要挨着求出小于k的所有偶数出现的概率相加,在取一下膜即可。但是k很大,直接枚举求和肯定不行,推导一下后发现那个数就是二项式定理的展开式,数学上我们给出(a+b)的n次方加上(a-b)的n次方可以吧二项式定理展开后的偶数项去掉,由此即得所求概率的分子就是p的k次方加上(p-2*q)的k次方的一半,分母就是p的k次方,再用数论中的逆元知识求解一下取模操作就是答案。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
const int mod = 1e9+7;
typedef long long ll;

//求逆元
ll exgcd(ll a,ll b,ll &x,ll &y) {
    if(!a&&!b)return -1;
    if(b==0) {
        x=1;
        y=0;
        return a;
    }
    ll d=exgcd(b,a%b,y,x);
    y-=a/b*x;
    return d;
}

ll inv(ll a,ll n) {
    ll x,y;
    ll d=exgcd(a,n,x,y);
    if(d==1)return(x%n+n)%n;
    return -1;
}
//快速幂
ll poww(ll a,ll b,ll k) {
    ll ans=1,base=a;
    base%=k;
    while(b!=0) {
        if(b&1!=0)
            ans*=base;
        ans%=k;

        base*=base;
        base%=k;
        ans%=k;
        b>>=1;

    }
    ans%=k;
    return ans;
}

int main() {
    //freopen("in.txt","r",stdin);
    ll T;
    cin>>T;
    while(T--) {
        ll p,q,k;
        cin>>p>>q>>k;
        ll b =poww(p,k,mod);
        b=inv(b,mod);
        ll x=poww(p,k,mod),y=poww(p-2*q,k,mod);
        ll tmp=((x+y)*inv(2,mod))%mod;
        cout<<(tmp*b)%mod<<endl;
    }
    return 0;
}



 类似资料: