题意:
给k,n,求C(k,n)的约数个数。
解析:
首先对任意的素数p,n!中有 t(n) = (n / p + n / p^2 + n / p^3 + n / p^4 ......)个素因子 。
而:C(k,n) = n! / [(n - k)! * k!] 。
所以原数可以表示为 U = p1^a1 * p2^a2 * p3^a3 * p4^a4......ps^as.
其中pi为素数,ai = t(n) - t(k) - t(n - k) .
再由因子和的定理,可以知道:
因子个数:tao(U) = (a1 + 1) * (a2 + 1) * (a3 + 1)....* (as + 1).
有一个注意点是。。。素数表的时候别开方。。。不然打不到431。。。
代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <map>
#include <climits>
#include <cassert>
#define LL long long
using namespace std;
const int maxn = 431 + 10;
int prime[maxn];
bool isprime[maxn];
int nprime;
void prime_table()
{
//int m = sqrt(maxn + 0.5);
nprime = 0;
memset(isprime, true, sizeof(isprime));
memset(prime, 0, sizeof(prime));
for (int i = 2; i <= maxn; i++)
{
if (isprime[i])
{
prime[++nprime] = i;
for (int j = i * i; j <= maxn; j+= i)
{
isprime[j] = false;
}
}
}
}
int Count(int x, int pri)
{
int res = 0;
int t = 1;
while (t <= x)
{
t *= pri;
res += x / t;
}
return res;
}
int main()
{
#ifdef LOCAL
freopen("in.txt", "r", stdin);
#endif // LOCAL
int n, k;
prime_table();
while (~scanf("%d%d", &n, &k))
{
LL ans = 1;
for (int i = 1; i <= nprime && prime[i] <= n; i++)
{
int a = Count(n, prime[i]);
int b = Count(k, prime[i]);
int c = Count(n - k, prime[i]);
ans = ans * (a - b - c + 1);
}
printf("%lld\n", ans);
}
return 0;
}