zoukankan      html  css  js  c++  java
  • 欧拉筛学习笔记

    线性筛质数

    代码

    int prime[MAXN],tot;
    bool is_prime[MAXN];
    void choose(int n)
    {
        memset(is_prime,1,sizeof(is_prime));
        is_prime[1]=0;
        for(int i=2;i<=n;i++)
        {
            if(is_prime[i])
                prime[++tot]=i;
            for(int j=1;j<=tot&&i*prime[j]<=n;j++)
            {
                is_prime[i*prime[j]]=0;
                if(i%prime[j]==0)
                    break;
            }
        }
    }
    

    分析

    算法分析

    考虑你在设计一个线性筛质数算法

    你想,既然要做到“线性”,那么每个数必须只能被筛一次

    所以我们猜想,一个合数只会被它的最小素因数筛去

    代码分析

    memset(is_prime,1,sizeof(is_prime));
    

    首先假设所有数都是素数

    is_prime[1]=0;
    

    确定$1$不是素数

    for(int i=2;i<=n;i++)
    

    枚举所有$[1,N]$区间内的数

    if(is_prime[i])
        prime[++tot]=i;
    

    如果它在之前的筛选中“存活”下来,那么它一定是个素数,把它加入素数列表

    for(int j=1;j<=tot&&i*prime[j]<=n;j++)
    

    枚举i与一个素数能组成的所有合数,注意不要让它们超过n

    is_prime[i*prime[j]]=0;
    

    标记为合数

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

    关键一步

    如果i可以有一个素数因子,就跳出循环

    为什么呢?

    我们先来看线性筛质数的规则:

    一个合数只会被它的最小素因数筛去

    如果i有别的素因数了,那么坚强证明它不是接下来的合数的最小素因数

    所以为了保证运行效率,要跳出循环

    时间复杂度

    $$ T(N) = O(N) $$

    参考文献

    1. 欧拉筛筛素数 - 学委的博客
  • 相关阅读:
    C++中的头文件和源文件
    串口VMIN VTIME 详解
    lms111,rplidar 方向和起始角
    Nginx访问限制配置
    Nginx请求限制配置
    Nginx模块详解
    Nginx默认配置语法
    Nginx编译参数详解
    Nginx安装目录详解
    Nginx的快速安装
  • 原文地址:https://www.cnblogs.com/XZDXRZ/p/12369063.html
Copyright © 2011-2022 走看看