线性筛质数法
法一:埃式筛法
思想大体就是:
一个数是质数,那这个数的倍数(除了1)一定不是质数。
比如2是素数,那筛掉2*2,2*3,2*4......
3是素数,那筛掉3*3,3*4,3*5......
找n以内的质数:假设p是素数,那筛掉p*p,p*(p+1)......p*(n/p);
p枚举到logn即可,因为:
假设a*b=n,a为更小的那个,则a*a<=n,a<=logn;
那么代码实现:
1 const int maxn=100000; 2 boo isprime[maxn]; 3 void searchPrime(int n){ 4 memset(isprime,true,sizeof(isprime)); 5 isprime[1]=false; 6 for (i=2; i*i<=n; i++) 7 if (isprime(i)){ 8 j=i*i; 9 while (j<=maxn){ 10 isprime[j]=false; 11 j+=i;
} 12 } 13 } 14
但是这个方法做了一些无用功。
比如筛12时,作为2的倍数和3的倍数都被筛了一回,导致时间变长。
欧拉筛法就没有这个毛病。
二.欧拉筛法
原理是:
代码:
1 void oula(int n){//que是质数列,isprime为1是质数,为0不是质数 2 num=0; 3 memset(isprime,1,sizeof(isprime));//预设所有都为质数 4 isprime[0]=0; 5 isprime[1]=0; 6 for(int i=2;i<=n;i++){ 7 if(isprime[i]){//若是一个质数入列 8 num++; 9 que[num]=i; 10 } 11 //筛掉表里的数与自己的积 12 for(int j=1;j<=num&&i*que[j]<=n;j++){//i*que[j]<=n很重要不然1000都过不了 13 isprime[i*que[j]]=0; 14 if(i%que[j]==0)break;//碰到是自己最小的质因子 15 //因为质数不会在这个表里有质因子,不担心 16 } 17 } 18 }
EG.轻拍牛头
无愧于心,不困于情。