题解:学而思编程 计算因质数

【题目来源】

学而思编程:计算因质数

【题目描述】

小猴非常喜欢研究数学问题,这天他学习了质因数的定义,觉得很有意思,他想每个大于 \(1\) 的数 \(x\) 都会有若干的质因数,如果把 \(x\) 的质因数乘起来会有什么规律和特殊的性质么?他把这个乘积定义为“因质数”,决定深入研究一下,那第一步就是先把每个数的“因质数”求出来。

现在给出 \(N\) 个正整数,求出每个数的因质数是多少。

【输入】

第一行一个正整数 \(N\),表示数的个数;

第二行 \(N\) 个正整数 \(X_1,X_2,\dots,X_N\)

【输出】

一行用空格隔开的 \(N\) 个正整数,分别表示 $ X_1,X_2,\dots,X_N$ [的因质数。

【输入样例】

2
8 13

【输出样例】

2 13

【核心思想】

  1. 问题分析:给定 \(N\) 个正整数,求每个数的"因质数"——即该数所有不同质因数的乘积。例如 \(8 = 2^3\),质因数为 \(\{2\}\),因质数为 \(2\)\(13\) 是质数,因质数为 \(13\)。这是一个筛法预处理 + 质因数分解问题,关键在于利用类似埃氏筛的方法,预处理每个数的最小质因数并累乘不同质因数。

  2. 算法选择

    • 线性筛思想:遍历每个质数 \(i\),将 \(i\) 的倍数中尚未被赋值或需要乘上 \(i\) 的位置更新
    • 预处理标记f[x] 存储 \(x\) 的所有不同质因数的乘积
  3. 关键步骤

    • 预处理函数 init()
      • 遍历 \(i\)\(2\)\(10^6\)
        • f[i] == 0\(i\) 是质数):
          • 遍历 \(j\)\(i\)\(10^6\),步长 \(i\)\(i\) 的所有倍数):
            • f[j] == 0f[j] = i(首次遇到质因数,赋值)
            • 否则:f[j] *= i(累乘新的质因数)
    • 主函数
      • 调用 init() 预处理
      • 读取 \(N\)
      • 遍历每个数 \(x\):输出 f[x]
  4. 时间/空间复杂度

    • 时间复杂度:\(O(V \log \log V)\)\(V = 10^6\),类似埃氏筛的复杂度
    • 空间复杂度:\(O(V)\),预处理数组 f[1..V]
  5. 筛法预处理的核心思想

    • 质因数乘积的累积性:每个合数的因质数等于其所有不同质因数的乘积。当用质数 \(i\) 筛其倍数时,若该倍数首次被筛则赋值 \(i\),否则乘上 \(i\),确保每个质因数只贡献一次
    • 最小质因数优先:由于从小到大遍历,每个数第一次被赋值的是其最小质因数,后续更大的质因数通过 *= 累乘
    • 离线预处理:值域固定为 \(10^6\),与查询无关,预先计算所有数的因质数,查询时 \(O(1)\) 输出
    • 重复质因数处理f[j] == 0 的判断确保同一质因数的幂次只乘一次,实现"不同质因数"的要求
    • 适用于"多查询 + 固定值域质因数统计"类问题,筛法预处理将每次查询优化到常数时间

【算法标签】

质数

【代码详解】

#include <bits/stdc++.h>
using namespace std;
// 预处理
int n, x, f[1000005];
void init()
{
    for (int i=2; i<=1000000; i++) {  // 计算质因数模板
        if (f[i]==0) {  // 如果f[i]没有数字
            for (int j=i; j<=1000000; j+=i) {  // 从2遍历到1000000,按i的倍数步进
                if (f[j]==0) f[j] = i;  // 将每个f[j]初始化为i,如2,3,5...。
                else f[j] *= i;  // 然后每次计算,乘上i这个质数(因为有了f[i]==0判断,即乘以过i的不再乘i)
            }
        }
    }
}
int main()
{
    init();  // 预处理每个数的质因数乘积
    cin >> n;
    while (n--) {
        scanf("%d", &x);
        printf("%d ", f[x]);
    }
    return 0;
}

【运行结果】

2
8 13
2 13
posted @ 2026-07-05 14:35  团爸讲算法  阅读(6)  评论(0)    收藏  举报