问题描述
有n个不同的小球,编号为1~n。求从这n个小球中取出至少m个小球的方案数。
输入格式
输入一行,包含两个整数n和m。
输出格式
输出一个整数,表示方案数模10^9+7的结果。
样例输入
6 3
样例输出
42
数据规模和约定
对于30%的数据,3<=n<=10^3
对于60%的数据,3<=n<=10^6
对于100%的数据,3<=n<=10^9,3<=m<=10^5
题解
快速幂+DFS
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int mod=1000000007; 4 const int MAXN=1000010; 5 long long n,m,f[MAXN],v[MAXN]; 6 long long dfs(long long pos){ 7 if(pos==n-m+2){ 8 return pos*v[n-pos+1]%mod; 9 } 10 return pos*((v[n-pos+1]+dfs(pos-1))%mod)%mod; 11 } 12 long long ksm(long long a,long long p){ 13 long long ans=1; 14 while(p){ 15 if(p&1){ 16 ans=ans*a%mod; 17 } 18 a=a*a%mod; 19 p>>=1; 20 } 21 return ans; 22 } 23 int main(){ 24 cin>>n>>m; 25 f[0]=1; 26 for(long long i=1;i<=m;i++){ 27 f[i]=f[i-1]*i%mod; 28 } 29 v[1]=1; 30 for(long long i=2;i<=m;i++){ 31 v[i]=(mod-mod/i)*v[mod%i]%mod; 32 } 33 v[0]=1; 34 for(long long i=1;i<=m;i++){ 35 v[i]=v[i]*v[i-1]%mod; 36 } 37 long long ans=dfs(n)+1; 38 cout<<(ksm(2,n)-ans+mod)%mod<<endl; 39 return 0; 40 }