组合数算法
C(n,m)=n!/m!*(n-m)!
开始是想当然用逆元来写了,但n较大时就会算不了了。
参考代码:
#include<iostream>
#include<vector>
#include<cmath>
using namespace std;
//计算n以下的质因数
vector<int> nPrime(int n)
{
vector<int> v;
for(int k=2;k<=n;k++)
{
int isprime=1;
int s=sqrt(k);
for(int t=2;t<=s;t++)
{
if(k%t==0){
isprime=0;break;
}
}
if(isprime)v.push_back(k);
}
return v;
}
//计算n!中素数m的次数
int dPrime(int n, int m) {
int pow = 0;
while (n >= m)
{
int temp = n / m;
pow += temp;
n = temp;
}
return pow;
}
//计算组合数C(n,m,p)
int Cnm(int n, int m,int p) {
long long ans = 1;
vector<int> v = nPrime(n);
for (int i = 0; i < v.size(); i++) {
int pow = dPrime(n, v[i]) - dPrime(m, v[i]) - dPrime(n - m, v[i]);
for (int j = 0; j < pow; j++) {
ans *= v[i];
ans %= p;
}
}
return ans;
}
int main()
{
int n, m, p;
cin>>n>>m>>p;
cout << Cnm(n,m,p)<<endl;
return 0;
}
参考于博客:组合数算法