码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2018-07-25 18:59:54      阅读:119      评论:0      收藏:0      [点我收藏+]

标签:empty   prim   线性筛   模拟   完整   表示   一个   for   复杂   

原理:

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

假设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;
  }
}

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

标签:empty   prim   线性筛   模拟   完整   表示   一个   for   复杂   

原文地址:https://www.cnblogs.com/djf666/p/9367517.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!