📅  最后修改于: 2023-12-03 15:11:34.817000             🧑  作者: Mango
素数指的是只能被 $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++ 的介绍。判断素数和筛素数是算法竞赛中常用的算法。在实际使用中,应根据具体情况选择适当的算法,在满足时间和空间要求的情况下,尽量提高程序的效率和正确性。