列表

详情


NC207423. 扔硬币

描述

有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

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++11(clang++ 3.9) 解法, 执行用时: 147ms, 内存消耗: 1900K, 提交时间: 2020-06-01 11:02:20

#include<bits/stdc++.h>
using namespace std;

const int mod=1e9+7;
int fastpow(long long a,int b)
{
	long long s=1;
	for(;b;b>>=1,a=a*a%mod)if(b&1)s=s*a%mod;
	return s;
}
long long ans,A[100005],B[100005];
long long C(int n,int m)
{
	return A[n]*B[m]%mod*B[n-m]%mod;
}
int main()
{
    int i,n,m,k,t;
    for(A[0]=i=1;i<=1e5;i++)A[i]=A[i-1]*i%mod;
    B[100000]=fastpow(A[100000],mod-2);
    for(i=99999;i>=0;i--)B[i]=B[i+1]*(i+1)%mod;
    scanf("%d",&t);
    while(t--)
    {
    	scanf("%d%d%d",&n,&m,&k),ans=0;
    	if(n-m<k){printf("0\n");continue;}
    	for(i=m;i<=n;i++)ans=(ans+C(n,i))%mod;
    	printf("%lld\n",C(n,k)*fastpow(ans,mod-2)%mod);
	}
}

C++14(g++5.4) 解法, 执行用时: 94ms, 内存消耗: 1220K, 提交时间: 2020-05-31 18:59:27

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5,mod=1e9+7;
ll ksm(ll a,ll n){
	 ll ans=1;
	 while(n){
	 	 if(n&1) ans=ans*a%mod;
	 	 a=a*a%mod;
	 	 n>>=1;
	 }
	 return ans;
}
ll fac[N]={1};
inline ll C(int n,int k){
	return fac[n]*ksm(fac[n-k]*fac[k]%mod,mod-2)%mod;
}
#define mst(a) memset(a,0,sizeof a)
int main(){
	int t,n,m,k;
	for(int i=1;i<=N-5;i++)
		fac[i]=fac[i-1]*i%mod;
	scanf("%d",&t);
	while(t--){
		scanf("%d%d%d",&n,&m,&k);
		if(m+k>n) puts("0");
		else {
			ll a=C(n,k),b=ksm(2,n);
			for(int i=0;i<m;i++)
				b=(b-C(n,i)+mod)%mod;
			printf("%lld\n",a*ksm(b,mod-2)%mod);
		}
	}
	return 0;
} 

上一题