Divisors POJ - 2992(求阶乘素因子)

Divisors POJ - 2992

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

题意:

求组合数 C n k 的因子个数

分析:

根据公式:

C n k = n ! k ! ( n k ) !

同样是运用算术基本定理

我们枚举每一个素因子p,求出n!中多个p记为cnt1,k!中多少个p记为cnt2,(n-k)!中有多少个p记为cnt3

因为k!和(n-k)!作为分母因此势必会减少n!中的p,那么整个组合数中素因子p的个数应该是

cnt1-cnt2-cnt3

根据约数个数求和公式可以直接求出

code:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
const int maxn = 500;
bool isprime[maxn];
int prime[maxn],cnt;
void init(){
    cnt = 0;
    memset(isprime,true,sizeof(isprime));
    isprime[0] = isprime[1] = false;
    for(int i = 2; i < 500; i++){
        if(isprime[i]){
            prime[cnt++] = i;
            for(int j = i + i; j < 500; j += i){
                isprime[j] = false;
            }
        }
    }
}
int resolve(int n,int p){
    int ans = 0;
    while(n){
        ans += n / p;
        n /= p;
    }
    return ans;
}//计算阶乘中含有多少个p
int main(){
    init();
    int n,k;
    while(~scanf("%d%d",&n,&k)){
        ll ans = 1;
        for(int i = 0; i < cnt && prime[i] <= n; i++){
            ans *= (resolve(n,prime[i]) - resolve(k,prime[i]) - resolve(n-k,prime[i]) + 1);
        }
        printf("%lld\n",ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/codeswarrior/article/details/81394139