欧拉筛
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 ; }
代码如上。
以前我一直以为埃拉托斯特尼筛法是线性的,后来发现,写的完美的是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] 的时候就不筛他了,这就保证每一个合数只被筛了一次。
以上是关于欧拉筛的主要内容,如果未能解决你的问题,请参考以下文章