欧拉筛

Posted Dark猫

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了欧拉筛相关的知识,希望对你有一定的参考价值。

技术分享
#include<bits/stdc++.h>
using namespace std ;
const int maxn = 1000000 ;
bool isprime[maxn];
int prime[maxn];

int init()
{
    int cntprime = 1 ;
    for( int i = 2 ; i <= maxn ; i++)
    {
        if( !isprime[i] )
            prime[cntprime++] = i ;
        for( int j = 1 ; j < cntprime && prime[j]  * i <= maxn ; j++)
        {
            isprime[i*prime[j]] = true ;
            if( i % prime[j] == 0 )
                break ; 
        }
    }
    return cntprime - 1 ; 
}
View Code

代码如上。

 

以前我一直以为埃拉托斯特尼筛法是线性的,后来发现,写的完美的是O(nlognlogn),我的甚至能有O(n^2)级,所以,学习一发欧拉筛(O(n))

 

线性筛对一般的筛法改动不大。

主要是第一维是i第二维是prime[j] ( 与一般筛法相反)

另外就是神奇的代码:

 

i % prime[j] == 0 , break ;

 

这样就保证了每个合数只被标记处理筛了一次(避免一般筛法像30这样的数字 在 2* 15 , 5 * 6 都会筛到,筛了多次效率降低的问题)

 

关于这个 i % prime[j] 的说明,

 

首先第一维是i,第二维是prime[j],

如果 i% prime[j] == 0 ,则有 k*prime[j] = i ,那么对于i * prime[j+1] (下一次循环),可等价于 k*prime[j] * prime[j+1]  即就是 k‘*prime[j+1],该合数会在i循环到k‘次被筛到,所以在 k*prime[j] * prime[j+1] 的时候就不筛他了,这就保证每一个合数只被筛了一次。

 

以上是关于欧拉筛的主要内容,如果未能解决你的问题,请参考以下文章

欧拉筛&&线性筛

关于欧拉筛筛素数

欧拉筛法模板代码

欧拉筛转载自用

线性筛素数(欧拉筛)

线性筛素数(欧拉筛)