https://nanti.jisuanke.com/t/17115
題意:有一枚不均勻的硬幣,正面朝上的概率是q/p。現在拋k次硬幣,求其中有偶數次正面朝上的概率爲X/Y,現在要求輸出X*(Y對於1e9+7的逆元)。
題解:
for(int i=0;i<=k;i+=2){
ans+=C(k,i)*(1-q/p)^(k-i)*(q/p)^i;
}
可以看出這是一個牛頓二項式,但是求的是偶數項。
根據牛頓二項式有:
偶數項+奇數項=(a+b)^k=1
偶數項-奇數項=(a-b)^k=(1-2*q/p)^k
所以偶數項=(1+(1-2*q/p)^k)/2
其中要求逆元
代碼:
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<vector>
#include<string>
#include<bitset>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<iomanip>
#include<iostream>
#define debug cout<<"aaa"<<endl
#define d(a) cout<<a<<endl
#define mem(a,b) memset(a,b,sizeof(a))
#define LL long long
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define MIN_INT (-2147483647-1)
#define MAX_INT 2147483647
#define MAX_LL 9223372036854775807i64
#define MIN_LL (-9223372036854775807i64-1)
using namespace std;
const int N = 100000 + 5;
const LL mod = 1000000000 + 7;
const double eps = 1e-8;
LL exgcd(LL a,LL b,LL &x,LL &y){
if(b==0){
x=1;
y=0;
return a;
}
LL r=exgcd(b,a%b,x,y);
LL t=x;
x=y;
y=t-a/b*y;
return r;
}
LL quick(LL a,LL b){
LL ans=1;
a%=mod;
while(b){
if(b&1)
ans=(ans*a)%mod;
a=(a*a)%mod;
b>>=1;
}
ans%=mod;
return (ans+mod)%mod;
}
int main(){
int t;
LL p,q,k,temp,x,y,ans;
scanf("%d",&t);
while(t--){
scanf("%lld%lld%lld",&p,&q,&k);
temp=quick(p,k);
exgcd(temp,mod,x,y);
ans=(quick(p-2*q,k)*x)%mod;
ans=1+ans;
exgcd(2,mod,x,y);
ans=(ans*x)%mod;
ans=(ans+mod)%mod;
printf("%lld\n",ans);
}
return 0;
}