POJ2992 Divisors(整数分解)

Divisors
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 10847   Accepted: 3214

Description

Your task in this problem is to determine the number of divisors of  Cnk. Just for fun -- or do you need any special reason for such a useful computation?

Input

The input consists of several instances. Each instance consists of a single line containing two integers n and k (0 ≤ k ≤ n ≤ 431), separated by a single space.

Output

For each instance, output a line containing exactly one integer -- the number of distinct divisors of  Cnk. For the input instances, this number does not exceed 2 63 - 1.

Sample Input

5 1
6 3
10 4


Sample Output

2
6
16

题目大意:

Cnk的素数因子的个数,由于n和k偏大,直接计算后算素数因子的个数显然不可能,所以我们可以利用一些数论技巧,我们需要知道几条定理:


(1) :n!的素因子分解中的素数p的幂为:

[n/p] + [n/p^2] + [n/p^3] ......+[n/p^n],(n >= p ^ n)

(2):若n的标准素因子分解表达式为n = p1 ^ a1 + p2 ^ a2 + p3 ^ a3 + ......pn^an,n的正因子的个数为ans = (a1 + 1) * (a2 + 1) * (a3 + 1) ......*(an + 1).


解题思路:

由于题目n和k给的范围是431,所以打表431以内的素数,然后依次从小到大枚举素数,计算幂值,当枚举完所有的素数幂值后,套用公式二得解。然后题目给的是Cnk,所以必须化成阶乘的形式。Cnk = n! / (n-k)!k!,计算的时候只要上面减掉下面两个就可以了。


AC代码:

#include
#include
#include
using namespace std;

const int maxn = 1000;
bool isprime[maxn];
int prime[maxn];
int nprime;
int cnt[maxn];

void doprime() //筛法
{
	long long i,j;
	nprime = 0;
	memset(isprime,true,sizeof(isprime));
	isprime[1] = 0;
	for(i=2;i<=450;i++)
	{
		if(isprime[i])
		{
			prime[++nprime] = i;
			//cout<



你可能感兴趣的:(数论)