最近学习了求素数的线性筛法,和大家分享一下。
作用
1.求 1 - N 的所有素数
2.求每个数的最小质因子
优势
在处理数据量大的时候速度快,可以比埃氏筛快很多倍。
时间复杂度O(n)
介绍
不断找到一个素数,然后将其在范围内的所有倍数筛去。
首要要准备几个变量
1. N 决定求素数的范围
2. primes[N] 这个数组用来存放素数
3. cnt 存放素数时候用的指针
4. st[N] st[i]为0表示这个数字没被筛过 1表示这个数字被筛过
5. minp[N] 保存一个数的最小质因子
准备好以上这些后就可以发车啦!
取i从2开始进行遍历
第一个判断语句判断这个数字是否被筛过
第二个循环语句处理primes数组中存放的素数 取其与i的倍数
以下是模板
const int N=1e8;
int primes[N],cnt; // 存放质数
bool st[N]; // 当前数是否被筛
int minp[N]; // 保存最小质因子
int get_primes(int n) // 欧拉筛 O(n)
{
for(int i=2;i<=n;i++)
{
if(!st[i]) // 若i没被筛去 此时i必为质数
{
minp[i]=i; // i的最小的质因子为i
primes[cnt++]=i; // 将i保存在primes数组中 cnt往后移动一位
}
for(int j=0;i*primes[j]<=n;j++)
{
int t=primes[j]*i; // 得到质数的倍数
st[t] = true; // 质数的倍数被筛去
minp[t]=primes[j]; // 质数的倍数最小的质因子就是该质数
if(i%primes[j]==0) break;
// 若i是之前素数的倍数
// 说明这个倍数会在后面的循环内被筛去
// 没有必要继续循环了
}
}
}
和大家学习交流一下 有错误和不足请批判指正