📜  素数模板 c++ (1)

📅  最后修改于: 2023-12-03 15:11:34.817000             🧑  作者: Mango

素数模板 C++
什么是素数?

素数指的是只能被 $1$ 和自身整除的正整数。例如,$2$、$3$、$5$、$7$、$11$ 都是素数,但 $4$、$6$、$8$ 都不是素数。素数在数学中有很多重要的应用,例如密码学和组合数学等。

如何判断一个数是否为素数?

判断一个数是否为素数有很多方法,其中比较常见的方法包括试除法、试除法优化(筛法)和 Miller-Rabin 算法等。

试除法

试除法是最简单的素数判断方法之一。其基本思想是将待判断的数与 $2$ 到 $\sqrt{n}$ 之间的每个数依次相除,如果能整除,则说明该数不是素数。

bool is_prime(int n) {
    if (n < 2) return false;
    for (int i = 2; i * i <= n; i++) {
        if (n % i == 0) {
            return false;
        }
    }
    return true;
}

筛法

筛法是一种简单而有效的素数筛法。其基本思想是从 $2$ 开始,依次将其倍数标记为合数,知道最大数为止。最终留下来的就是素数。筛法分为欧拉筛和线性筛两种。

欧拉筛

欧拉筛又称埃氏筛,是最简单的筛法之一。其时间复杂度为 $O(n\log\log n)$。其基本思想是从 $2$ 开始,依次将其倍数标记为合数,知道最大数为止。最终留下来的就是素数。

const int N = 1000000;
int prime[N], cnt;
bool st[N];
void get_primes(int n) {
    for (int i = 2; i <= n; i++) {
        if (!st[i]) {
            prime[cnt++] = i;
            for (int j = i + i; j <= n; j += i) {
                st[j] = true;
            }
        }
    }
}
线性筛

线性筛是欧拉筛的改进版,其时间复杂度为 $O(n)$。其基本思想是每个合数只会被它的最小质因子筛掉。

const int N = 1000000;
int prime[N], cnt;
bool st[N];
void get_primes(int n) {
    for (int i = 2; i <= n; i++) {
        if (!st[i]) {
            prime[cnt++] = i;
        }
        for (int j = 0; prime[j] <= n / i; j++) {
            st[prime[j] * i] = true;
            if (i % prime[j] == 0) {
                break;
            }
        }
    }
}
总结

以上就是素数模板 C++ 的介绍。判断素数和筛素数是算法竞赛中常用的算法。在实际使用中,应根据具体情况选择适当的算法,在满足时间和空间要求的情况下,尽量提高程序的效率和正确性。