197 阶乘分解(考虑枚举顺序)

1. 问题描述:

给定整数 N,试把阶乘 N! 分解质因数,按照算术基本定理的形式输出分解结果中的 pi 和 ci 即可。

输入格式

一个整数 N。

输出格式

N! 分解质因数后的结果,共若干行,每行一对 pi,ci,表示含有 pi ^ ci 项。按照 pi 从小到大的顺序输出。

数据范围

3 ≤ N ≤ 10 ^ 6

输入样例:

5

输出样例:

2 3
3 1
5 1
样例解释
5! = 120 = 2 ^ 3 ∗ 3 ∗ 5
来源:https://www.acwing.com/problem/content/199/

2. 思路分析:

这道题目非常经典,因为n最大为10 ^ 6所以不可能直接计算出来再分解,其中一种比较容易想到的方法是依次枚举当前的数字n,n - 1,...2,计算阶乘中每一个数字x的质因子出现的次数,但是这样做的时间复杂度为:n√n = 10 ^ 9肯定会超时的,所以不能够使用这种方法来解决,我们其实可以换一种枚举的顺序,可以先筛出当前1~n的所有质数,然后再枚举质因子出现的次数:

5! = 5 * 4 * 3 * 2 * 1,枚举n的质因子,对于质数p来说出现的次数为:⌊n / p⌋ + ⌊n / (p ^ 2)⌋ + ...,1~10^6大概有:10 ^ 6 / (log10^6) ≈ 50000,而对于所有质数p出现的次数为:log2 10^6 + log3 10 ^ 6 + .... ≈ 5000 * log2 10 ^ 6.

3. 代码如下:

from typing import List


class Solution:
    count = 0
    
    # 线性筛求解2~n的质数, 包括数字n
    def init(self, n: int, primes: List[int], st: List[int]):
        for i in range(2, n):
            if st[i] == 0:
                primes[self.count] = i
                self.count += 1
            j = 0
            while primes[j] * i < n:
                st[primes[j] * i] = 1
                if i % primes[j] == 0:
                    break
                j += 1

    def process(self):
        n = int(input())
        self.count = 0
        primes, st = [0] * (n + 10), [0] * (n + 10)
        self.init(n + 1, primes, st)
        for i in range(self.count):
            p = primes[i]
            j, s = n, 0
            while j > 0:
                s += j // p
                j //= p
            print(p, s)


if __name__ == '__main__':
    Solution().process()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值