链接:https://ac.nowcoder.com/acm/contest/5757/D
来源:牛客网
题目描述
有n枚硬币,每枚硬币扔出来是正面和反面的概率各占50%。小明同时扔下了n枚硬币后,已知至少有m枚硬币是反面。请问恰好有k枚硬币是正面的概率是多少。
输入描述:
输入t,代表有t组数据。每组数据输入一个数n,m,k,代表有n枚硬币,抛出以后至少有m枚是反面的情况下,恰好有k个正面的概率。
(t<=1000,n<1e5,m<=1000,k<=n)
输出描述:
对于结果是p/q,输出分数取模1e9+7后的结果。
示例1
输入
1
10 3 5
输出
797520667
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
const int maxn=1e5+5;
const int mod=1e9+7;
ll fact[maxn];
ll infact[maxn];
ll ksm(ll a,ll b) /// a^b
{
ll ans=1;
while(b)
{
if(b&1) ans=ans*a%mod;
a=a*a%mod;
b>>=1;
}
return ans;
}
void init()
{
fact[0]=1;
infact[0]=1;
for(int i=1;i<maxn;i++)
{
fact[i]=fact[i-1]*i%mod;
infact[i]=infact[i-1]*ksm(i,mod-2)%mod;
}
}
ll C(ll a, ll b)
{
return fact[a]%mod*infact[b]%mod*infact[a-b]%mod;
}
int main()
{
init();
int t;
scanf("%d",&t);
while(t--)
{
ll n,m,k;
scanf("%lld%lld%lld",&n,&m,&k);
if(m+k>n)
{
printf("0\n");
continue;
}
ll x=ksm(2,n);
ll y=C(n,k);
for(int i=0;i<m;i++)
{
x=(x-C(n,i)+mod)%mod;
}
ll ans=y*ksm(x,mod-2)%mod;
printf("%lld\n",ans);
}
}