一个多月没做题了。好好加油,将算法搞好
有两个公式可以解决这个问题:对于任于的数p = n1 ^p1 * n2 ^ p2 * n3 * p3 ..... p的因数个数为(1 + p1) * (1 + p2) * (1 + p3).... (1)
对 n!的质因子p的个数为(n/p + n /(p^2) + n (p ^3) + ...)
c(n,m) = n!/(m! * (n - m)! 只要求出n!的所有对应的质因子个数,然后减去相应的m!的所有对应的质因子个数和(n-m)!的所有对应的质因子个数,最后用公式1可求出结果。
因为m! 和(n-m)!的所有质因子,是n!的所有质因子的子集
#include <iostream>
#include <cstdio>
#include <cstring>
const int MAXN = 431;
bool prime[MAXN + 2] = {1,1,0};
int totalPrime[MAXN];
long long divisorIndex[MAXN + 2];
int cnt = 0;
void fprime()
{
int i;
int j;
for(i = 2; i <= MAXN; i++)
{
if(prime[i] == false)
{
totalPrime[cnt++] = i;
for(j = i + i; j <= MAXN; j+= i)
{
prime[j] = true;
}
}
}
}//print all the prime number within the scope of 431
void primeNum(int n,bool isplus)
{
int i,j;
for(i = 0; i < cnt; i++)
{
if(totalPrime[i] > n)
{
break;
}
}//before the index i in the array of totalPrime is the prime smaller than n
for(j = 0; j < i; j++)
{
// printf("prime %d\n",totalPrime[j]);
int temp = totalPrime[j];
while(temp <= n)
{
if(isplus == true)
divisorIndex[totalPrime[j]] += n / temp;//accumulate the number of all primes divisors for n!
else
divisorIndex[totalPrime[j]] -= n / temp;//minus the number of all primes divisor for (m!) or (n -m)!
temp *= totalPrime[j];
}
}
}
long long sumDivisor()
{
long long ans = 1;
int i;
long long sum = 0;
for(i = 2; i <= MAXN; i++)
{
if(divisorIndex[i] > 0)
{
ans *= (divisorIndex[i] + 1);//(p1 + 1)(p2 + 2)(p3 + 3)...
sum++;
}
}//compute the sum of divisors,which is the proble's ans
//if(sum == 1)
// return ans - 1;
if(sum == 0)
return 1;
return ans;
}
int main()
{
fprime();
int n,m;
//freopen("d.in","r",stdin);
//freopen("2992.out","w",stdout);
while(scanf("%d %d",&n,&m) != EOF)
{
memset(divisorIndex, 0, sizeof(divisorIndex));
long long ans;
primeNum(n,true);
primeNum(n -m,false);
primeNum(m,false);
ans = sumDivisor();
printf("%lld\n",ans);
}
return 0;
}