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


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

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

    先发个普通筛法

    #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]){}这里去除了一些重复筛的可能.如何将所有重复的现象去除呢?

    于是我们有了欧拉筛法.

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

    废话不说上代码再讲.

    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 (精确的)
  • 相关阅读:
    一步步学习微软InfoPath2010和SP2010--第六章节--发布并提交表单数据(6)--关键点
    一步步学习微软InfoPath2010和SP2010--第六章节--发布并提交表单数据(5)--管理员批准模板
    一步步学习微软InfoPath2010和SP2010--第六章节--发布并提交表单数据(4)--作为内容类型发布
    一步步学习微软InfoPath2010和SP2010--第六章节--发布并提交表单数据(3)--提交到SharePoint
    一步步学习微软InfoPath2010和SP2010--第六章节--发布并提交表单数据(2)--提升栏目
    一步步学习微软InfoPath2010和SP2010--第六章节--发布并提交表单数据(1)--发布方法
    release
    CMake 入门实战,从实例入手,讲解 CMake 的常见用法,例如aux_source_directory的用法
    为 CmakeLists.txt 添加 boost 组件
    Linux下使用CMake进行编译的时候寻找Boost库
  • 原文地址:https://www.cnblogs.com/tmzbot/p/4006032.html
Copyright © 2020-2023  润新知