zoukankan      html  css  js  c++  java
  • 素数筛法

    今天并不是十分愉快

    在gg面前吐槽素数个数那道题很简单,然后发现我早就忘了欧拉筛怎么写

    这就十分令人(尴)(尬)了。

    于是,我下定决心

    整理一下素数的筛法(其实只有两种,rua)

    首先是埃斯托拉尼特筛法

    埃氏筛:从2开始,将每一个质数的倍数都标记成合数,从而筛选出质数(未被标记的)。

      visit[0]=visit[1]=1;//0和1显然不是素数
      for(int i=2;i<=MAXN;i++){
        if(!visit[i]){ //如果i是素数
          for(int j=i*i;j<=MAXN;j+=i){
            visit[j]=i;
          }
        }
      }
    
    

    因为不同的人寻找素数筛法的目的是不相同的,因此这里并不会贴上完整的代码。

    如果有什么需要的话可以自己进行不全。

    另外补充:

    关于为什么j=i*i

    我并不能说这是显然,但是大家可以仔细思考一下。


    举个栗子:

    对于i=7而言,

    如果我们取到了j小于7,例如5,

    显然之前在对5进行判断的时候已经筛过了5*7,

    那么自然就会出现重复的情况。

    最后是欧拉筛法(怪怪的)

    欧拉筛

    其实按照我个人的知识范围而言,所知道的筛法只有欧拉筛和埃氏筛(也许吧)。

    所以我们自然而然的就要比较一下两种筛法的区别。


    经过了长时间的探索,翻了无数个题解,无数篇博客。

    终于在zdx大神的指导下,我悟了。

    其实欧拉筛和埃氏筛最大的差别就在于一行代码。

    如果没有那一行代码,那么其实欧拉筛本身是要比埃氏筛复杂的。

    (但是同样不要想把埃氏筛加上一行代码使他更加简洁,两者的循环本质不同,无法实现)

    这一行代码是:

    if(i%is_prime[j]==0)break;

    zdx说很少有人能理解这段代码,然而我悟了?

    那就还是说一下本人的拙见:

    在欧拉筛整体代码(详见本文末尾)的大环境之下,这段代码还是比较好理解的。

    他的根本作用就是为了防止筛合数的重复。

    因为对于欧拉筛的操作而言,在没有这行代码的情况下,

    我们所进行的操作就是把所有的质数从1到n乘一遍得到合数(并不一定能够乘到n),

    但是这样的操作就意味着一个问题,

    还是一个栗子:

    比如说4*3=12,

    我们对12进行了一次标记。

    但是当i=6的时候,便利j=2,6*2=12,我们又进行了一次标记,

    相当于进行了二次的操作。

    而对于这行代码,

    显然我们省略了这段重复判断的过程。

    妙啊~

    #include<cstdio>
    #include<iostream>
    #include<vector>
    using namespace std;
    int is_prime[10000000];
    int n,tot=0;
    bool a[1000000001];
    int main(){
      scanf("%d",&n);
      a[1]=true;
      for(int i=2;i<=n;i++){
        if(!a[i]){
          is_prime[tot++]=i;
        }
        for(int j=0;j<tot&&is_prime[j]*i<=n;j++){
          a[is_prime[j]*i]=true;
          if(i%is_prime[j]==0)break;
        }
      }
      printf("%d",tot);
      return 0;
    }
    
    

    上面是洛谷的P3912 素数个数AC代码,注意数组范围,我曾经因此RE,TLE,WA

    祝大家OI愉快。

    ——by 某个不知名的精分患者

  • 相关阅读:
    Linux问题汇总
    Linux问题汇总
    朴素贝叶斯分类器
    捕捉异常信息
    异常处理类
    sqlserver2008链接服务器的使用和oracle11g客户端修改字符集
    抛出异常
    添加水印
    验证码
    sqlserver数据库备份
  • 原文地址:https://www.cnblogs.com/JingFenHuanZhe/p/SuShuShaiFa0916.html
Copyright © 2011-2022 走看看