欧拉筛证明:
首先介绍一下算术基本原理:
x
=
p
1
e
1
∗
p
2
e
2
∗
p
3
e
3
x=p_1^{e1} * p_2^{e_2} * p_3^{e_3}
x=p1e1∗p2e2∗p3e3…(p为质数,e为正数,x为任意不为1的正整数)
由上可以知道任意一个合数都是由一个质数乘以一个其他数字组成!
所以我们可以通过枚举一个质数和一个其他非
1
1
1的正整数来判断来其他合数。
但是为了提高其运算速率,我们想要对于任意一个合数仅判断一次时我们可以考虑,采用其最小的质数就行了,因为最小的质数只有一个且另一个非
1
1
1正整数数仅用一次,那么任意一个合数只会判断一次咯
代码
void erlu(int n){
int i,j,k;
for(i=1;i<=n;i++) vis[i]=pri[i]=0;
for(i=2;i<=n;i++){枚举非1正整数
if(!vis[i]){
pri[++tot]=i;
}
for(j=1;j<=tot&&(i*pri[j]<=n);j++){//枚举素数
vis[i*pri[j]]=pri[j];//保存质数表,每一个空间表示该下标的最小质数!
if(i%pri[j]==0) break;//原因在下注明
}
}
}
- reak的原因是如果该循环继续下去的话(i*pri[j]的最小素数其实不是pri[j],而是之前能被整除的那个素数,不break的话,一个合数的判断次数就会增加)
- 数组范围能开到1e7也就是说在能快速判断1e7的所有素数,同时能通过遍历质数表判断到1e14。
证明:因为1e14=1e7*1e7,只需要判断1e14以内任意数对整个素数表进行遍历,如果都无法整除,则有本身至少为两个大于1e7的质数之积(算术基本定理)或者是本身一个质数。而因为范围是1e14,排除第一种情况,所以为合数!整除了就是合数。 - 素数密度:x/ln(x)