NC207423. 扔硬币
描述
输入描述
输入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; }