线性筛选(埃拉托斯特尼筛法升级版欧拉筛法)

Posted djf666

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线性筛选(埃拉托斯特尼筛法升级版欧拉筛法)相关的知识,希望对你有一定的参考价值。

原理:

任何一个合数都可以表示成一个质数和一个数的乘积

假设A是一个合数,且A = x * y,这里x也是一个合数,那么有:

A = x * y; (假设y是质数,x合数)

x = a * b; (假设a是质数,且a < x——>>a<y)

-> A = a b y = a Z (Z = b y)

即一个合数(x)与一个质数(y)的乘积可以表示成一个更大的合数(Z)与一个更小的质数(a)的乘积,那样我们到每一个数,都处理一次,这样处理的次数是很少的,因此可以在线性时间内得到解。

仍然按上面的例子模拟(这里0为是素数,1为非素数,p为记录的素数表):

初始:

1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

p(empty)

然后到2的位置,把2放入素数表,做当前范围内可以筛掉的处理(具体是怎样的看代码叭):

1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

p 2 到3,把3放入素数表,继续处理

1 0 0 1 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0

p 2 3 然后到了4,它不是个素数,也处理一下

1 0 0 1 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0

p 2 3 .......

然后一直搞下去,最后也能得到完整的素数表,这样虽然看起来复杂一些,但是实际上我们发现对于每个数的处理几乎是O(1)的。

void get_list(){
for(int i=2;i<=maxn;i++){
  if(!isPri[i]) prime[++tot]=i;
  for(int j=1;j<=tot&&i*prime[j]<=maxn;j++){
    isPri[i*prime[j]]=1;
    if(i==j) break;
  }
}








以上是关于线性筛选(埃拉托斯特尼筛法升级版欧拉筛法)的主要内容,如果未能解决你的问题,请参考以下文章

欧拉线性筛 和 欧拉函数的求值

小航的算法日记素数筛选

素数筛选

数论部分第二节:埃拉托斯特尼筛法

欧拉筛(线性筛)

线性筛素数欧拉函数