线性筛法(欧拉筛法)求素数

孤者浪人 提交于 2020-03-21 14:05:57

写$\text{O}\left( n \log{\log{n}}\right)$的筛法很长时间了,我却从来没想过它的优化.偶然间看到线性筛法,心想大约是不错的优化,于是便爬去学习下.

首先,$\text{O}\left( n \log{\log{n}}\right)$的筛法肯定要比$\text{O}\left( n\right)$的慢,虽然在现在的机子上不明显.还是不要将$\text{O}\left( n \log{\log{n}}\right)$比较靠谱.但是线性筛法有着它自己的用途.

先发个普通筛法

#include <cmath>
bool sieve[1000000];
int prime[1000000],ps,temp,temp2,temp3;
void normal_sieve(int n){
	temp=sqrt(n)+10;
	for(i=2;i<temp;++i){
		if(!sieve[i]){
			prime[ps++]=i;
			temp2=(n/i)+1;
			temp3=i;
			for(j=2;j<=temp2;++j){
				temp3+=i;
				sieve[temp3]=true;
			}
		}
	}
	for(;i<=n;++i){
		if(!sieve[i]){
			prime[ps++]=i;
		}
	}
}//包含了几乎所有有用功能的普通筛法

(orz神犇WJZ先)

如何把筛法优化到线性呢?

注意到在普通筛法中我们的优化if(!sieve[i]){}这里去除了一些重复筛的可能.如何将所有重复的现象去除呢?

于是我们有了欧拉筛法.

欧拉筛法通过不筛除筛除过的数来将时间复杂度优化到$\text{O}\left( n\right)$,也就是每个合数都筛去一遍.这个时间不会超过$\text{O}\left( n\right)$.加上扫一遍的确是线性的.

废话不说上代码再讲.

 

bool IsPrime[10000001];
int Pri[2000001],PriN;
int FindPrime ( int MaxN ) {
	for( int i = 2 ; i <= MaxN ; ++i ){
		if( IsPrime[ i ] )
			Pri[ PriN++ ]=i; //将这句话放在下面的循环前以保证PriN和Pri值的完整性
		for(int j=0;j<PriN;++j){
			if( i*Pri[ j ] > MaxN )
				break; //当过大了就跳出
			IsPrime[ i * Pri[ j ] ] = 0;
			//筛去素数
			if( i % Pri[ j ] == 0 ) break;
			//这里是关键,如果i是一个合数(这当然是允许的)而且i mod prime[j] = 0
			//那么跳出,因为i*prime[ (- over -)j ]一定已经被筛去了,被一个素因子比i小的数
		}
	}
} 
对比:(普通筛法在下,经过优化)
200:
Euler :               46        0.00000000
Eratosthenes :        46        0.00000000
239:
Euler :               51        0.00000000
Eratosthenes :        52        0.00000000
286:
Euler :               61        0.00000000
Eratosthenes :        61        0.00000000
343:
Euler :               68        0.00000000
Eratosthenes :        68        0.00000000
411:
Euler :               80        0.00000000
Eratosthenes :        80        0.00000000
493:
Euler :               94        0.00000000
Eratosthenes :        94        0.00000000
591:
Euler :              107        0.00000000
Eratosthenes :       107        0.00000000
709:
Euler :              126        0.00000000
Eratosthenes :       127        0.00000000
850:
Euler :              146        0.00000000
Eratosthenes :       146        0.00000000
1019:
Euler :              170        0.00000000
Eratosthenes :       171        0.00000000
1222:
Euler :              199        0.00000000
Eratosthenes :       199        0.00000000
1466:
Euler :              232        0.00000000
Eratosthenes :       232        0.00000000
1759:
Euler :              273        0.00000000
Eratosthenes :       274        0.00000000
2110:
Euler :              317        0.00000000
Eratosthenes :       317        0.00000000
2531:
Euler :              369        0.00000000
Eratosthenes :       370        0.00000000
3037:
Euler :              434        0.00000000
Eratosthenes :       435        0.00000000
3644:
Euler :              510        0.00000000
Eratosthenes :       510        0.00000000
4372:
Euler :              596        0.00000000
Eratosthenes :       596        0.00000000
5246:
Euler :              697        0.00000000
Eratosthenes :       697        0.00000000
6295:
Euler :              818        0.00000000
Eratosthenes :       818        0.00000000
7553:
Euler :              958        0.00000000
Eratosthenes :       958        0.00000000
9063:
Euler :             1126        0.00000000
Eratosthenes :      1126        0.00000000
10875:
Euler :             1322        0.00000000
Eratosthenes :      1322        0.00000000
13049:
Euler :             1554        0.00000000
Eratosthenes :      1555        0.00000000
15658:
Euler :             1826        0.00000000
Eratosthenes :      1826        0.00000000
18789:
Euler :             2143        0.00000000
Eratosthenes :      2143        0.00000000
22546:
Euler :             2520        0.00000000
Eratosthenes :      2520        0.00000000
27055:
Euler :             2965        0.00000000
Eratosthenes :      2965        0.00000000
32465:
Euler :             3483        0.00000000
Eratosthenes :      3483        0.00000000
38957:
Euler :             4103        0.00000000
Eratosthenes :      4103        0.00000000
46748:
Euler :             4830        0.00000000
Eratosthenes :      4830        0.00000000
56097:
Euler :             5691        0.00000000
Eratosthenes :      5691        0.00000000
67316:
Euler :             6706        0.00000000
Eratosthenes :      6706        0.00000000
80779:
Euler :             7905        0.00000000
Eratosthenes :      7906        0.00000000
96934:
Euler :             9330        0.00000000
Eratosthenes :      9330        0.00000000
116320:
Euler :            10988        0.00000000
Eratosthenes :     10988        0.00000000
139583:
Euler :            12972        0.00000000
Eratosthenes :     12972        0.00000000
167499:
Euler :            15302        0.00000000
Eratosthenes :     15302        0.00000000
200998:
Euler :            18061        0.00000000
Eratosthenes :     18061        0.00000000
241197:
Euler :            21317        0.00000000
Eratosthenes :     21317        0.01600000
289436:
Euler :            25181        0.00000000
Eratosthenes :     25181        0.00000000
347323:
Euler :            29767        0.00000000
Eratosthenes :     29767        0.00000000
416787:
Euler :            35135        0.00000000
Eratosthenes :     35135        0.00000000
500144:
Euler :            41548        0.00000000
Eratosthenes :     41548        0.01600000
600172:
Euler :            49108        0.01500000
Eratosthenes :     49108        0.00000000
720206:
Euler :            58044        0.00000000
Eratosthenes :     58044        0.01600000
864247:
Euler :            68661        0.01500000
Eratosthenes :     68661        0.01600000
1037096:
Euler :            81210        0.01600000
Eratosthenes :     81210        0.01500000
1244515:
Euler :            96065        0.01600000
Eratosthenes :     96065        0.01500000
1493417:
Euler :           113703        0.03100000
Eratosthenes :    113703        0.01600000
1792100:
Euler :           134513        0.03200000
Eratosthenes :    134513        0.03200000
2150519:
Euler :           159280        0.03200000
Eratosthenes :    159280        0.03200000
2580622:
Euler :           188550        0.03200000
Eratosthenes :    188550        0.03100000
3096746:
Euler :           223297        0.04700000
Eratosthenes :    223297        0.04600000
3716095:
Euler :           264452        0.06300000
Eratosthenes :    264452        0.06300000
4459313:
Euler :           313275        0.07800000
Eratosthenes :    313275        0.07800000
5351175:
Euler :           371197        0.09400000
Eratosthenes :    371197        0.10900000
6421409:
Euler :           439770        0.09400000
Eratosthenes :    439770        0.14000000
7705690:
Euler :           521256        0.12500000
Eratosthenes :    521256        0.15600000
9246827:
Euler :           617847        0.15600000
Eratosthenes :    617847        0.20300000
11096192:
Euler :           732467        0.18700000
Eratosthenes :    732467        0.23400000
13315430:
Euler :           868429        0.20300000
Eratosthenes :    868429        0.29700000
15978515:
Euler :          1029823        0.25000000
Eratosthenes :   1029823        0.36000000
19174217:
Euler :          1221415        0.29700000
Eratosthenes :   1221415        0.45300000
23009060:
Euler :          1448793        0.37500000
Eratosthenes :   1448793        0.54700000
27610871:
Euler :          1718770        0.43800000
Eratosthenes :   1718770        0.67200000
33133045:
Euler :          2039320        0.53100000
Eratosthenes :   2039320        0.78100000
39759653:
Euler :          2420000        0.64100000
Eratosthenes :   2420001        0.96800000
47711583:
Euler :          2871837        0.79700000
Eratosthenes :   2871837        1.17200000
57253899:
Euler :          3408686        0.95300000
Eratosthenes :   3408686        1.42200000
68704678:
Euler :          4046322        1.14000000
Eratosthenes :   4046322        1.71900000
82445613:
Euler :          4803832        1.39100000
Eratosthenes :   4803832        2.07800000
98934735:
Euler :          5703624        1.67200000
Eratosthenes :   5703624        2.53100000

但是题目一般来说不会出这么丧心病狂的数据晚些发放更大的测试数据链接: http://pan.baidu.com/s/1eQCcD8Y 密码: 1ck6链接: http://pan.baidu.com/s/1kTh0qov 密码: jcya (精确的)
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!