http://poj.org/problem?id=2992
该题用到的定理:
.任意一个数n可以写成若干个素数的乘积,即 p1^a1 * p2^a2*......*pn^an,它的的约数的个数为 (a1+1)*(a2+1)*......(an+1).
.对于任意一个素数p, n!中含有p的个数为 (n/p + n/p^2 + n/p^3 + ......).
.c(n,k) = n! / ( k! * (n-k)! ).
#include <stdio.h>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <math.h>
#include <string.h>
#define LL long long
#define _LL __int64
const int N = 500;
int prime[N];
int prime_num;
bool vis[N];
void Prime()
{
prime_num = 0;
memset(vis,true,sizeof(vis));
for(int i = 2; i < 500; i++)
{
if(vis[i])
{
for(int j = i*2; j < 500; j += i)
vis[j] = false;
}
}
for(int i = 2; i <= 431; i++)
if(vis[i])
prime[ prime_num++ ] = i;
}
//n!中含有素数p的个数
int cal(int n, int p)
{
int ans = 0;
int tmp = p;
while(p <= n)
{
ans += n/p;
p = p*tmp;
}
return ans;
}
int main()
{
int n,k;
Prime();
while(~scanf("%d %d",&n,&k))
{
LL ans = 1;
for(int i = 0; i < prime_num; i++)
{
int a = cal(n,prime[i]);
int b = cal(k,prime[i]);
int c = cal(n-k,prime[i]);
ans *= (a-b-c+1);
}
printf("%lld\n",ans);
}
return 0;
}