标签:50000 筛去 质数 枚举 详解 数组 线性 合数 欧拉
看到埃氏筛的缺点,同学们可能会想,有没有筛法能够将一个数只筛一遍呢?答案是肯定的。
线性筛思想:这个合数只会被它的最大非自身因数(对应最小质因数)筛。 这样能保证每个合数只会被筛一次。
时间复杂度:\(O(n)\),
Code:
bool a[50000];
a[1]=1;//注意1不是质数;
int p[50000],t;
for(int i=2;i<=n;i++)
{
if( a[i] == 0 )
p[++t]=i;//是质数就记录;
for(int j=1;j<=t && i*p[j]<=n;j++)
{
a[ i*p[j] ]=1;//标记合数;
if( i%p[j] == 0 )
break;
//保证同一个合数不会被多个质数标记。
}
}
最小质因数 × 最大因数(非自己) = 这个合数
\(p\) 数组中的质数是递增的,当i能整除 \(p[ j ]\) ,那么 \(i\times p[j+1]\) 这个合数肯定会被 \(p[ j ]\) 乘某个数筛掉。因此直接 \(break\),将 \(i\times p[j+1]\)以及之后的数筛掉。
这个方法可以保证每个数都被筛掉,但又只被筛一次。
程序运行:2 加入 \(p\) 数组,枚举质数(只有2),筛去质数与 2 的乘积(筛去 4)。3 加入 \(p\) 数组(现在有2、3),枚举质数,筛去 3 与质数的乘积(筛去6、9)。4 不是质数,不加入 \(p\) 数组,枚举质数,筛去8;此时 \(4 \mod 2=0\) ,触发了 \(break\)。
如果你还不理解,让我们来看表格。
i | 质数 | 筛去的合数 |
---|---|---|
2 | 2 | 4 |
3 | 2、3 | 6、9 |
4 | 2、3 | 8 |
5 | 2、3、5 | 10、15、25 |
其余以此类推。 |
标签:50000,筛去,质数,枚举,详解,数组,线性,合数,欧拉 来源: https://www.cnblogs.com/JXYBJ/p/xianxingshai.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。