素数

可能出现“质数”、“素数”混用的情况,见谅。

定义

一个正整数无法被除了 1 和它自身之外的任何自然数整除,则称该数为质数,否则称其为合数。

注意到在整个自然数集合中,质数数量不多、分布稀疏,对于一个 足够大NZN 的质数大约有 NlnN 个。换句话说,lnN 个数中大约有 1 个质数。

质数判定与筛选

试除法

我们知道若 NZN 为合数,则必定存在一个能整除 N 的数 M 满足 2MN

可以写出代码:

bool IsPrime(int x) {
    if (x == 0 || x == 1)
        return 0;
    for (int i = 2; i * i <= x; i++) {
        if (x % i == 0)
            return 0;
    }
    return 1;
}

基于随机化的判定有 Miller-Robbin

Eratosthenes

思想是对于任意 x 的倍数 x,2x,3x, 都不是质数,所以从 2 开始倍数筛掉,往后若一个数 x 尚未被标记,意味着其不能被 [2,x1] 整除,则其为质数。

然后同上试除法,为了防止形如 6=3×2 同时被 2,3 筛两次的情况(小于 x2 的数 x 的倍数在扫描更小的数就已经筛过了),从 x2 开始,标记 x2,(x+1)x,,Nxx 即可。

void Prime(const int n) {
    memset(v, 0, sizeof(v));
    for (int i = 2; i <= n; i++) {
        if (v[i])
            continue;
        p[++tot] = i;
        for (int j = i; j <= n / i; j++)
            v[i * j] = 1;
    }
}

复杂度为 O(pN,pPNp)=O(NloglogN),接近线性,是 OI 中最常见的筛法。

线性筛

我们是怎么优化暴力筛的?通过枚举倍数来减少总的枚举次数。但是优化后我们的埃氏筛还是会重复标记某些合数,例如 12 会被 2×63×4 同时标记。那我们能否唯一确定出一种筛选出某个数的做法:即我们 能否确定某个数唯一产生的方式

我们正式引入线性筛:线性筛通过“从小到大累积质因子”的方式标记每个合数,这里直接给出易懂的代码:

处理的手段其实就是通过确定唯一产生数的方式来确定唯一的“遍历”方式。

int v[N], p[N];

void Prime(const int n) {
    m = 0;
    memset(v, 0, sizeof(v));
    for (int i = 2; i <= n; i++) {
        if (!v[i]) { v[i] = i; p[++m] = i; }    // 质数
        // 给当前的数 i 乘上一个质因子
        for (int j = 1; j <= m; j++) {
            // i 有比 p[j] 更小的质因子,或者已经超出了 n 的范围
            if (p[j] > v[i] || p[j] > n / i)
                break;
            // p[j] 是合数 i * p[j] 的最小质因子
            v[i * p[j]] = p[j];
        }
    }
}

复杂度为 O(n),真正的线性筛法。

算数基本定理

这非常重要。

任何一个大于 1 的正整数都能唯一分解有限个质数的乘积,形式化地:

N=p1c1p2c2pmcm

其中 ciZ,piP,p1<p2<<pm

结合试除法和埃氏筛我们就可以进行一个质因数的分解,复杂度为 N

void DivideNum(const int n) {
    m = 0;
    for (int i = 2; i * i <= n; i++) {
        if (n % i == 0) {   // i 是质数
            p[++m] = i;
            c[m] = 0;
            while (n % i == 0) { c /= i; c[m]++; }      // 抹掉所有 i
        }
    }
    if (n > 1) { p[++m] = n; c[m] = 1; }    // n 是质数
}

有一种效率更高的 Pollard's Rho 用于优化复杂度。

posted @   起汐  阅读(17)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示