题解阶乘因子

Posted kcn999

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了题解阶乘因子相关的知识,希望对你有一定的参考价值。

题目描述

        桐桐刚刚学习了自然数N的阶乘:阶乘(N!)被定义成从1到N的所有整数的乘积,例如5!=5×4×3×2×1=120。随着数N的增大,N!增长的非常快,5!=120,10!=3628800。桐桐想到了一种方法来列举那么大的数:不是直接列出该数,而是按照顺序列举出该数中各个质数因子出现的次数。如825可描述为(0 1 2 0 1),意思是对825分解质因数,这些质数因子中有0个2,1个3,2个5,0个7,1个11。请你编一个程序,读入N值,帮助桐桐按顺序输出N!所包含的质数因子的个数。

 

输入输出格式

输入格式

        一行,一个整数N。(2≤N≤100000)

 

输出格式

        一行,一个N!中所包含的质数因子的个数(从最小的质数开始)的序列,数与数之间用一个空格隔开。

 

输入输出样例

输入样例

53

 

输出样例

49 23 12 8 4 4 3 2 2 1 1 1 1 1 1 1

 

题解

        表面上看枚举每一个因子的质因子很麻烦,其实可以顺推,枚举每一个数可以作为哪些数的质因子,在这个过程中顺便可以把合数给筛掉。

        有一个可以优化的地方:素数除了2以外都为奇数,可以利用这个特性使枚举时间减半。

技术分享图片
#include <iostream>
#include <cstdio>

using namespace std;

int n;
int a[100001];
int p[100001];

int main()
{
    scanf("%d", &n);
    int tmp;
    for(register int i = 4; i <= n; i += 2)
    {
        tmp = i;
        while(!(tmp & 1)) tmp >>= 1, ++a[2];
        p[i] = 1;
    } 
    printf("%d", a[2] + 1);
    for(register int i = 3; i <= n; i += 2)
    {
        if(p[i]) continue;
        for(register int j = i + i; j <= n; j += i) 
        {
            tmp = j;
            while(!(tmp % i)) tmp /= i, ++a[i];
            p[j] = 1;
        } 
        printf(" %d", a[i] + 1);
    }
    return 0;
}
参考程序

 

以上是关于题解阶乘因子的主要内容,如果未能解决你的问题,请参考以下文章

CH 3101 - 阶乘分解 - [埃筛]

[航海协会]稀疏阶乘问题

[航海协会]稀疏阶乘问题

XDU1019 阶乘因子的个数

组合数(阶乘数质因子分解)

请问计算n的阶乘末尾有多少个0