存个组合数板子
预处理阶乘求组合数
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll mod=1e9+7;
const ll maxn=1e6+7;
ll pr[maxn];
void init()//预处理一下阶乘
{
pr[0]=1;
for(int i=1;i<=maxn;i++)
{
pr[i]=pr[i-1]*i%mod;
}
}
ll fpow(ll a,ll b)//快速幂
{
a%=mod;
ll ans=1;
while(b)
{
if(b&1) ans=ans*a%mod;
a=a*a%mod;
b>>=1;
}
return ans%mod;
}
ll c(ll a,ll b)//打表查询
{
if (a < b || a < 0 || b < 0) return 0;
return pr[a]*fpow(pr[b]*pr[a-b]%mod,mod-2)%mod;//逆元套公式
}
int main()
{
init();
int t;
scanf("%d",&t);
while(t--)
{
ll a,b;
scanf("%lld%lld",&a,&b);
printf("%lld\n",c(a,b));
}
return 0;
}
或者直接运算
ll _C(ll n,ll m)
{
ll ans=1;
if(m>(n+1)/2)
{
m=n-m;
}
for(ll i=1;i<=m;i++)
{
ans=ans*(n-i+1)%mod*fpow(i,mod-2)%mod;
}
return ans;
}
求n!中s的个数
ll factory(ll n,ll s)//计算N!中s的个数
{
ll sum=0;
int i=1;
while(n)
{
n=n/s;
sum+=n;
}
return sum;
}
下面是暴力质因数分解求组合数
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll mod=1e9+7;
map <ll, ll> m;
map<ll,ll>::iterator it;
void fun(ll n, ll k)
{
for(ll i=2; i*i<=n; i++)
{
if(n%i==0)
{
while(n%i==0)
{
m[i] += k;
n/=i;
}
}
}
if(n>1)
{
m[n] += k;
}
}
ll fpow(ll a,ll b)
{
a%=mod;
ll ans=1;
while(b)
{
if(b&1) ans=ans*a%mod;
a=a*a%mod;
b>>=1;
}
return ans%mod;
}
ll c(ll a,ll b)
{
if (a < b || a < 0 || b < 0) return 0;
ll ret=1;
b=min(a-b,b);
for(ll i=0; i<b; i++) fun(a-i,1);
for (ll i=b; i>=1; i--) fun(i,-1);
for (it= m.begin(); it!= m.end(); it++)
{
if (it->second != 0)
{
ret=(ret*fpow(it->first, it->second))%mod;
}
}
return ret;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
m.clear();
ll a,b;
scanf("%lld%lld",&a,&b);
printf("%lld\n",c(a,b));
}
return 0;
}