• 线性筛的简单证明


    原理

    线性筛是一种可以在线性时间内将素数筛选出来的算法,其中的主要思想在于保证合数只会被它的最小质因数筛掉并且筛掉一次

    代码

    下面是线性筛的算法CPP实现:

    vector<int> generate_primes_linear_time(int n) {
        vector<int> lp(n + 1);
        vector<int> primes;
        for (int i = 2; i <= n; ++i) {
            if (lp[i] == 0) {
                lp[i] = i;
                primes.push_back(i);
            }
            for (int j = 0; j < primes.size() && primes[j] <= lp[i] && i * primes[j] <= n; ++j)
                lp[i * primes[j]] = primes[j];
        }
        return primes;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    其中 l p [ i ] lp[i] lp[i]保存了 i i i的最小质因数 p r i m e s primes primes则是存储了从小到大的质数。

    简单证明

    所有的合数只会被筛掉一次

    假设存在一个合数被筛掉了两次,即存在合数 C = i ∗ p i = p j ∗ j ( p i > p j ) C=i*p_i=p_j*j(p_i>p_j) C=ipi=pjj(pi>pj),那么就可以得出它被两个不同的质数 p i , p j p_i,p_j pi,pj筛过两次,那么很容易得到 p j ∣   i p_j | \ i pj i,并且有 p i > p j p_i > p_j pi>pj,那么表明此时对于倍数 i i i的时候,在枚举到质数 p j p_j pj就会退出循环而不会枚举到 p i p_i pi,因此假设不成立。可以保证所有的合数有且并被筛过一次。

    下一个没有被筛掉的数字一定是素数

    假设下一个没有被筛掉的数字为 x x x,那么我们假设它不是素数,则有 x = p x ∗ q ( p x < x , q < x ) x=p_x*q(p_x < x, q < x) x=pxq(px<x,q<x)其中 p x p_x px x x x的最小质因数,那么对于倍数 q q q,在枚举素数的时候没有枚举到 p x p_x px,表明存在更加小的素数 p y p_y py使得 p y ∣   q p_y | \ q py q,因此也有 p y ∣   x p_y | \ x py x,所以 p x p_x px并不是 x x x的最小质因数。假设不成立,所以 x x x是素数。

  • 相关阅读:
    图片采集器-网页图片批量采集器免费
    CK草稿本
    Python Fire:自动生成命令行接口
    Centos7 安装gdal历程,使用node-gdal功能
    Spring中过滤器(Filter)和拦截器(Interceptor)的区别和联系
    随想录一刷Day41——动态规划
    移远通信联合产业中坚力量共同发起倡议,推动5G RedCap技术演进和应用创新发展
    seata的启动与使用
    【CodeForces】CF1700D River Locks
    css定位详解
  • 原文地址:https://blog.csdn.net/m0_51156601/article/details/133827997