存个组合数板子
预处理阶乘求组合数
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 const ll mod=1e9+7; 5 const ll maxn=1e6+7; 6 ll pr[maxn]; 7 void init()//预处理一下阶乘 8 { 9 pr[0]=1; 10 for(int i=1;i<=maxn;i++) 11 { 12 pr[i]=pr[i-1]*i%mod; 13 } 14 } 15 ll fpow(ll a,ll b)//快速幂 16 { 17 a%=mod; 18 ll ans=1; 19 while(b) 20 { 21 if(b&1) ans=ans*a%mod; 22 a=a*a%mod; 23 b>>=1; 24 } 25 return ans%mod; 26 } 27 ll c(ll a,ll b)//打表查询 28 { 29 if (a < b || a < 0 || b < 0) return 0; 30 return pr[a]*fpow(pr[b]*pr[a-b]%mod,mod-2)%mod;//逆元套公式 31 } 32 int main() 33 { 34 init(); 35 int t; 36 scanf("%d",&t); 37 while(t--) 38 { 39 ll a,b; 40 scanf("%lld%lld",&a,&b); 41 printf("%lld ",c(a,b)); 42 } 43 return 0; 44 }
或者直接运算
1 ll _C(ll n,ll m) 2 { 3 ll ans=1; 4 if(m>(n+1)/2) 5 { 6 m=n-m; 7 } 8 for(ll i=1;i<=m;i++) 9 { 10 ans=ans*(n-i+1)%mod*fpow(i,mod-2)%mod; 11 } 12 return ans; 13 }
求n!中s的个数
1 ll factory(ll n,ll s)//计算N!中s的个数 2 { 3 ll sum=0; 4 int i=1; 5 while(n) 6 { 7 n=n/s; 8 sum+=n; 9 } 10 return sum; 11 }
下面是暴力质因数分解求组合数
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 const ll mod=1e9+7; 5 map <ll, ll> m; 6 map<ll,ll>::iterator it; 7 void fun(ll n, ll k) 8 { 9 for(ll i=2; i*i<=n; i++) 10 { 11 if(n%i==0) 12 { 13 while(n%i==0) 14 { 15 m[i] += k; 16 n/=i; 17 } 18 } 19 } 20 if(n>1) 21 { 22 m[n] += k; 23 } 24 } 25 ll fpow(ll a,ll b) 26 { 27 a%=mod; 28 ll ans=1; 29 while(b) 30 { 31 if(b&1) ans=ans*a%mod; 32 a=a*a%mod; 33 b>>=1; 34 } 35 return ans%mod; 36 } 37 ll c(ll a,ll b) 38 { 39 if (a < b || a < 0 || b < 0) return 0; 40 ll ret=1; 41 b=min(a-b,b); 42 for(ll i=0; i<b; i++) fun(a-i,1); 43 for (ll i=b; i>=1; i--) fun(i,-1); 44 for (it= m.begin(); it!= m.end(); it++) 45 { 46 if (it->second != 0) 47 { 48 ret=(ret*fpow(it->first, it->second))%mod; 49 } 50 } 51 return ret; 52 } 53 int main() 54 { 55 int t; 56 scanf("%d",&t); 57 while(t--) 58 { 59 m.clear(); 60 ll a,b; 61 scanf("%lld%lld",&a,&b); 62 printf("%lld ",c(a,b)); 63 } 64 return 0; 65 }
素数筛
int cnt=0; vis[0]=1; vis[1]=1; for(int i=2;i<=maxn;i++) { if(!vis[i]) prime[cnt++]=i; for(int j=0;j<cnt&&i*prime[j]<=maxn;j++) { vis[i*prime[j]]=1; if(i%prime[j]==0) break; } }