zoukankan      html  css  js  c++  java
  • 关于欧拉筛筛素数

    观察如下欧拉筛代码:

     1 const int MAXN=30000001;
     2 int prime[MAXN];
     3 bool vis[MAXN];
     4 int Prime(int n){
     5     int cnt=0;
     6     memset(vis,0,sizeof(vis));
     7     for(int i=2;i<n;i++){
     8         if(!vis[i])
     9         prime[cnt++]=i;
    10         for(int j=0;j<cnt&&i*prime[j]<n;j++){
    11             vis[i*prime[j]]=1;
    12             if(i%prime[j]==0)
    13                 break;
    14         }
    15     }
    16     return cnt;
    17 }

    发现其流程如下:

    • 从1至n枚举,对于元素i
      •   判断其是否已被筛除?否,则已经确定其为质数
      •   枚举不大于i的最小质因子质数
        •   将i与这些质数乘积筛除;

    充分性:

    ——为什么流程第2行是正确的呢?

    任意合数k可表示为其 最小质因子pj数i 相乘(i:质数or合数)

    pj小于等于 数i最小质因子(否则该质因子才是k的最小质因子)

    所以只要数i被枚举,合数k即被筛除(见流程3,4行)

    由于i一定小于k,故当枚举到合数k时,她已经被删除啦(见流程1行)

    即,该流程满足使所有合数被数i与该合数最小质因子pj相乘的情况筛去

    效率:

    ——为什么这样快?

    在流程中,统计筛操作的次数:

    由于合数k只被数i该合数最小质因子pj相乘的情况筛去

    (当另一个数l想要与k的另一个大点的质因子pm筛去k时,她惊奇地发现她的最小质因子比pm大——因为pj正是她的最小质因子——这就意味着她不能筛k)

    所以所以合数只被筛了一次;

    视为O(n)的效率

    附上一个筛数的流程:

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

    枚举至2,并筛除:

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

    质数:2;

    枚举至3,并筛除:

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

    质数:2,3;

    枚举至4,并筛除:

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

    质数:2,3;

    枚举至5,并筛除:

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

    质数:2,3,5;

    枚举至6,并筛除:

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

    质数:2,3,5;

    枚举至7,并筛除:

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

    质数:2,3,5,7;

    然后重复以上过程,筛除,并记录质数;

    (由于最小质数2,与8相乘已经大与15,故该筛的早已筛了,现在主要是记录质数,但流程还得继续啊)

  • 相关阅读:
    python 写入txt的新方法
    python 对excel进行截图
    python 关于excel弹窗——请注意,您的文档的部分内容可能包含了文档检查器无法删除的个人信息解决方法
    python win32com 读取带密码的excel
    移动硬盘——显示盘符但打不开
    python datetime和time的一些疑惑解答 及 获取上年同期、上月等日期
    pyinstaller 打包exe程序读不到配置文件No such file
    Python之——爱心代码参与情人节
    《易学设计模式》-笔记
    "高级"数据库小结
  • 原文地址:https://www.cnblogs.com/nietzsche-oier/p/6595627.html
Copyright © 2011-2022 走看看