一.求组合数 I
题目来源:求组合数 I
#include<iostream>
using namespace std;
const int mod = 1e9+7;
long long f[2010][2010];
int main()
{
for(int i=0;i<=2000;i++)
{
for(int j=0;j<=i;j++)
{
if(!j) f[i][j]=1;
else f[i][j]=(f[i-1][j-1]+f[i-1][j])%mod;
}
}
int n;
cin>>n;
while(n--)
{
int a,b;
cin>>a>>b;
printf("%ld\n",f[a][b]);
}
}
二.求组合数 II
题目来源:求组合数 II
#include<iostream>
using namespace std;
const int mod=1e9+7,N=1e5+10;
typedef long long LL;
long long fac[N],infac[N];
int quick_pow(int a, int k, int p)
{
int res = 1;
while (k)
{
if (k & 1) res = (LL)res * a % p;
a = (LL)a * a % p;
k >>= 1;
}
return res;
}
int main()
{
int n;
fac[0]=infac[0]=1;
for(int i=1;i<=1e5;i++)
{
fac[i]=fac[i-1]*i%mod;
infac[i]=infac[i - 1] * quick_pow(i,mod-2,mod)%mod;
}
cin>>n;
while(n--)
{
int a,b;
cin>>a>>b;
cout<<(LL)fac[a] * infac[b] % mod * infac[a - b] % mod<<endl;
}
}
三.求组合数 III
题目来源:求组合数 III
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
LL qmi(int a,int k,int p)
{
LL res = 1;
while(k)
{
if(k&1)res = (LL)res*a%p;
k>>=1;
a = (LL)a*a%p;
}
return res;
}
int C(int a,int b,int p)//自变量类型int
{
if(b>a)return 0;//漏了边界条件
int res = 1;
// a!/(b!(a-b)!) = (a-b+1)*...*a / b! 分子分母都有b项
for(int i=1,j=a;i<=b;i++,j--)
{
res = (LL)res*j%p; //分子
res = (LL)res*qmi(i,p-2,p)%p;//分母
}
return res;
}
//卢卡斯定理
int lucas(LL a,LL b,int p)
{
if(a<p && b<p)return C(a,b,p);//lucas递归终点是a<p && b<p
return (LL)C(a%p,b%p,p)*lucas(a/p,b/p,p)%p;//a%p后肯定是<p的,所以可以用C(),但a/p后不一定<p 所以用lucas继续递归
}
int main()
{
int n;
cin >> n;
while(n--)
{
LL a,b;
int p;
cin >> a >> b >> p;
cout << lucas(a,b,p) << endl;
}
return 0;
}
四.求组合数 IV
题目来源:求组合数 IV
#include<bits/stdc++.h>
using namespace std;
const int N=5010;
int primes[N],cnt;
bool st[N];
int sum[N];
//高精度乘法
vector<int> mul(vector<int> a,int b)
{
vector<int> c;
int t=0;
for(int i=0;i<a.size();i++)
{
t+=a[i]*b;
c.push_back(t%10);
t/=10;
}
while(t)
{
c.push_back(t%10);
t/=10;
}
return c;
}
//求n!中质数p的指数
int get(int n,int p)
{
int res=0;
while(n)
{
res+=n/p;
n/=p;
}
return res;
}
//线性筛法2-n质数
void get_primes(int n)
{
for(int i=2;i<=n;i++)
{
if(!st[i]) primes[cnt++]=i;
for(int j=0;primes[j]<=n/i;j++)
{
st[primes[j]*i]=true;
if(i%primes[j]==0) break;
}
}
}
int main()
{
int a,b;
cin>>a>>b;
get_primes(a);//因为a>=a-b&&a>=b,筛最大数即可
for(int i=0;i<cnt;i++)
{
int p=primes[i]; //质数primes[i]的指数是sum[i]
sum[i]=get(a,p)-get(b,p)-get(a-b,p);
}
vector<int> res;
res.push_back(1);
for(int i=0;i<cnt;i++)
{
for(int j=0;j<sum[i];j++)
{
res=mul(res,primes[i]);//primes[0]^sum[0]+primes[1]^sum[1]+primes[2]^sum[2]+....
}
}
for(int i=res.size()-1;i>=0;i--) cout<<res[i];
cout<<endl;
}
五.满足条件的01序列
题目来源:满足条件的01序列
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 200010, mod = 1e9 + 7;
int qmi(int a, int k)
{
int res = 1;
while (k)
{
if (k & 1) res = (LL)res * a % mod;
a = (LL)a * a % mod;
k >>= 1;
}
return res;
}
int main()
{
int n;
cin >> n;
int a=2*n,b=n,res=1;
for(int i=a;i>=a-b+1;i--) res=(LL)res*i%mod;
for(int i=1;i<=b;i++) res=(LL)res*qmi(i,mod-2)%mod;
res=(LL)res*qmi(n+1,mod-2)%mod;
cout << res << endl;
return 0;
}