Poj2992Divisors 组合数求因子的个数

Divisors

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 263 - 1.

Sample Input

5 1
6 3
10 4

Sample Output

2
6
16

Source

题目大意:求组合数Cnk因子的个数

如果用暴力的做法肯定会TLE的, 那么该怎么做呢?

定理1, 设f(N) 为N因子的个数 , pi为质因子, ai为该质因子的个数

把N质因数分解得到 N = p1^a1 * p2^a2 * p3^a3*……*pi^ai

f(N) = (a1 + 1)*(a2 + 1) * (a3 + 1)*……*(ai + 1);

那么怎么求N! 呢

定理2,设每个质因子指数的个数为ei,  ei = [N/pi] + [N/(pi^2)] +[N/(pi^3)] +……+[N/(pi^i)]  直到 N/(pi^i) = 0

f(N!) = (e1 + 1)*(e2 + 1) *(e3 + 1)*……*(ei + 1)

Cnk = n! / (k! * (n - k)!)

首先打个素数表, 遍历一遍即可

#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <algorithm>
#include <functional>
#include <utility>
#include <bitset>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstdio>
#include <cstring>

using namespace std;

typedef long long int ll;
typedef pair<int, int> P;
int read() {
    int x=0,f=1;
    char ch=getchar();
    while(ch<‘0‘||ch>‘9‘) {
        if(ch==‘-‘)f=-1;
        ch=getchar();
    }
    while(ch>=‘0‘&&ch<=‘9‘) {
        x=x*10+ch-‘0‘;
        ch=getchar();
    }
    return x*f;
}
const double pi=3.14159265358979323846264338327950288L;
const double eps=1e-6;
const int mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const int INT = 0x7fffffff;
const int MAXN = 433;
const int xi[] = {0, 0, 1, -1};
const int yi[] = {1, -1, 0, 0};

int N, T;
int a[MAXN], cnt;//cnt记录素数的个数

void init() {//求素数
    cnt = 0;
    for(int i = 2; i <=431 ; i++) {
        int flag = 1;
        for(int j = 2; j*j <= i; j++) {
            if(i%j == 0) {
                flag = 0;
                break;
            }
        }
        if(flag) {
            a[cnt++] = i;
        }
    }
}
inline int cal(int n, int k){//计算指数的个数
   if(n < k) return 0;
   return n/k + cal(n/k, k);
}
int main() {
    init();
    int n, k;
    while(~scanf("%d%d", &n, &k)){
          ll  res = 1LL;
        for(int i = 0; i < cnt; i++){//遍历
            res *= 1LL*(cal(n, a[i]) - cal(k, a[i]) - cal(n-k, a[i]) + 1);
        }
        printf("%lld\n", res);

    }

    return 0;
}

 

时间: 2024-10-14 11:52:07

Poj2992Divisors 组合数求因子的个数的相关文章

hdu 6069 Counting Divisors(求因子的个数)

Counting Divisors Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)Total Submission(s): 3170    Accepted Submission(s): 1184 Problem Description In mathematics, the function d(n) denotes the number of divisors of

POJ2992:Divisors(求N!因子的个数,乘性函数,分解n!的质因子)

题目链接:http://poj.org/problem?id=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? 题目解析:这题也是TLE了无数遍,首先说一下求因子数目的函数是积性函数,积性函数即f(n)=f(a)*f(b)

POJ 2992-Divisors(求组合数质因子的个数)

Divisors Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 2992 Appoint description:  System Crawler  (2015-04-24) Description Your task in this problem is to determine the number of divisors of C

求因子个数和因子和

//求因子个数 int Facnt(int n) { int res = 1; for(int i=2;i*i<=n;i++) { if(n%i == 0) { int cnt = 0; do { n /= i; cnt++; }while(n%i==0); res *= (cnt+1); } } if(n > 1) res = 2*res; return res; } //求因子和 int Facsum(int n) { int res = 1; for(int i=2;i*i<=n;

LightOj 1278 - Sum of Consecutive Integers(求奇因子的个数)

题目链接:http://lightoj.com/volume_showproblem.php?problem=1278 题意:给你一个数n(n<=10^14),然后问n能用几个连续的数表示; 例如: 15 = 7+8 = 4+5+6 = 1+2+3+4+5,所以15对应的答案是3,有三种; 我们现在相当于已知等差数列的和sum = n, 另首项为a1,共有m项,那么am = a1+m-1: sum = m*(a1+a1+m-1)/2  -----> a1 = sum/m - (m-1)/2 a

Easy Number Challenge(暴力,求因子个数)

Easy Number Challenge Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submit Status Practice CodeForces 236B Appoint description:  System Crawler  (2016-04-26) Description Let's denote d(n) as the number of divisors of a

POJ-2992 Divisors---组合数求因子数目

题目链接: https://cn.vjudge.net/problem/POJ-2992 题目大意: 给出组合数Cnk,求出其因子个数,其中n,k不大于431,组合数的值在long long范围内 解题思路: 由于只有431种阶乘,先预处理431中素数,再预处理出每一个阶乘里面所含的素因子的指数,然后对于组合数,直接用素因子指数相减即可. 求出的质因子指数,就可以用定理直接求因子个数. 1 #include<iostream> 2 #include<cstdio> 3 #inclu

XDU1019 阶乘因子的个数

题意是让你求一个最小的N, 使得N!有M个0,N的阶乘中2的因子是远多于5的因子的个数, 因此我们统计出5的个数就知道其后面有几个0,对于一个数mid, mid!中5的因子的个数为mid/5 + mid/25 + mid/5^3 + ... 可以发现mid越大mid!中的5的个数越多, 因此我们可以二分答案, 代码如下: #include <cstdio> #include <cstring> #include <algorithm> #include <iost

欧拉计划013(ProjectEuler013):求出10个数乘积最大的

申明:之前的所有欧拉计划都是用python来写的,的确python来写,代码量极少,学习起来也很方便.但是最近为了找java工作,所以用Java来完成欧拉计划的题,来复习一下Java. Large sum Problem 13 Work out the first ten digits of the sum of the following one-hundred 50-digit numbers. 371072875339021027987979982208375902465101357402