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;
}