专栏文章
题解:P3383 【模板】线性筛素数
P3383题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mip897qz
- 此快照首次捕获于
- 2025/12/03 07:46 3 个月前
- 此快照最后确认于
- 2025/12/03 07:46 3 个月前
素数筛法
对于欧拉筛法,埃氏筛法仍然做了一些重复性的判断,比如 60 时取到素因子为 2、3、5 时均进行了标记,如果我们只用最小的质因数来进行筛选,则可以保证进行重复筛除,这样就可以把效率做到最好,这就是欧拉筛法。
欧拉筛法的算法步骤为:
- 枚举 中的每一个数 ;
- 如果 是素数,则保存在素数表中;
- 利用 和素数表中的素数 去筛除 。为了确保 只被素数 筛除,我们需要确保 是 中最小的素因子。
- 假设 中最小素因子是素数表中的 ,显然当 时, 都是可以被筛除的。
- 当 时,由于 不应该在此筛除,而应在 循环执行到 时,与素数表的 相乘才筛除,因此,需要在 时结束 循环。
CPP
void Euler_sieve(int n)
{
memset(p, true, sizeof p);
for (int i = 2; i <= n; i++)
{
if (p[i])
{
prime[++prime[0]] = i;
}
for (int j = 1; j <= prime[0] && i * prime[j] <= n; j++)
{
p[i * prime[j]] = false;
if (i % prime[j] == 0)
break;
}
}
}
每个数最多被筛选一次,时间复杂度 。
AC Code
CPP
#include <bits/stdc++.h>
using namespace std;
const int N = 1e8 + 100;
#define maxn 250005
#define mod 1e9 + 7
bool p[N];
int prime[N] = {0};
/*
void sieve(int n)//埃氏筛法
{
memset(p, true, sizeof p);
for (int i = 2; i * i <= n; i++)
{
if (p[i])
{
for (int j = i * i; j <= n; j += i)
{
p[j] = false;
}
}
}
}
*/
void Euler_sieve(int n)
{
memset(p, true, sizeof p);
for (int i = 2; i <= n; i++)
{
if (p[i])
{
prime[++prime[0]] = i;//把素数保存到素数表 prime 中
}
for (int j = 1; j <= prime[0] && i * prime[j] <= n; j++)
{
p[i * prime[j]] = false;//筛除 i*prime[j]
if (i % prime[j] == 0)
break;
}
}
}
int main()
{
int n, q, k;
cin >> n >> q;
Euler_sieve(n);//n 以内素数
while (q--)
{
cin >> k;
cout << prime[k] << "\n";//第 k 小素数
}
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...