分解质因数
单个数分解质因数
算法原理
采用试除法分解质因数即可
时间复杂度
或
阶乘分解质因数
给定整数 ,试把阶乘 分解质因数,按照算术基本定理的形式输出分解结果中的 和 即可。
5
2 3
3 1
5 1
一般方法分析
如果使用单个数分解质因数的方法,时间复杂度粗略估计为,对于n的1e6的数据范围,大概率会超时
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1e6 + 10;
int primes_cnt[N];
void divide(int n)
{
for (int i = 2; i <= n / i; ++ i)
{
if (n % i == 0)
{
int cnt = 0;
while (n % i == 0)
{
++ cnt;
n /= i;
}
primes_cnt[i] += cnt;
}
}
if (n > 1) ++ primes_cnt[n];
}
int main()
{
int n;
cin >> n;
for (int i = 2; i <= n; ++ i) divide(i);
for (int i = 2; i <= n; ++ i)
if (primes_cnt[i] > 0) cout << i << ' ' << primes_cnt[i] << endl;
return 0;
}
如果从优化的角度思考,如果能将divide中求cnt的过程进行预处理,快速求出n中质因子i的个数,复杂度会降低一些。
但实际考虑到预处理的时间复杂度为,并且由于n的变化,每次都需要预处理,这样预处理就没有什么意义了。
正解分析
在一般方法中,我们的思考方向是对于每个数都进行一次分解质因数
如果换种思考方向就是对于每一个质数,计算在阶乘中总共有多少个
算法原理
首先说明,上述的新的思考方向理论上是正确的,其可行性体现在以下的性质中
- 性质1: 中 质因子 的个数为 .(该性质的证明位于 质因数分解计算组合数)
使用该公式,对于每个质数而言,需要从 到 ,粗略计算为
而1到a中的质数个数为,所以粗略计算该算法的时间复杂度为
流程
- 首先使用线性筛筛取可能范围内的质数
- 利用上述公式分别计算每个质数的个数
代码实现
#include <iostream>
using namespace std;
const int N = 1e6 + 10;
int primes[N], cnt, st[N];
void init(int n)
{
for (int i = 2; i <= n; ++ i)
{
if (!st[i]) primes[cnt ++] = i;
for (int j = 0; primes[j] * i <= n; ++ j)
{
st[primes[j] * i] = true;
if (i % primes[j] == 0) break;
}
}
}
int main()
{
int n;
cin >> n;
init(n);
for (int i = 0; i < cnt; ++ i)
{
int p = primes[i], cnt = 0;
for (int j = n; j; j /= p) cnt += j / p; // 使用while还需要定义临时变量,不如for简洁
cout << p << ' ' << cnt << endl; // 不需要判断cnt是否为0,因为至少会是1,因为n!中一定包含小于n的质数,这些质数的质因子就是他们自身,所以所有的质数的指数最小也会是1
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理