• 数论2:素数筛


    埃氏筛

    判断素数可通过试除小于\(\sqrt n\)的素数来实现,那么将其反过来,只要将\(<= \sqrt n\)的素数的倍数都删掉,那么就能得到一张\(<=n\)的素数表,\(O(n\lg \lg n)\)

    // 需划掉合数,所以最初假设均为素数,即数组初始化为0
    bool composite[maxn];
    
    void generate(int n)
    {
        for(int i = 2, lim = sqrt(n); i <= lim; ++i) {
            if(composite[i]) continue;
            for(int j = i*i; j <= n; j += i)
                composite[j] = 1;
        }
        for(int i = 2; i < n; ++i)
            if(!composite[i]) printf("%d ", i);
        putchar('\n');
    }
    

    线性筛

    埃氏筛的问题在于一个合数可能会被多个素数删除,造成不必要操作。为解决该问题,注意到每个合数均可写成其最小素因数p乘C,即\(n=pC\),其中必有\(C \ge p\),因为若非如此,当C为素数时,不满足假设“p为最小素因数”;当C为合数时,其必能分解除小于C的素因数,同样不满足假设“p为最小素因数”。线性筛就是通过从小到大地遍历C来保证每个合数均被,其仅被删除一次。

    // composite同样初始化为0;np是素数个数;prime保存找到的素数
    bool composite[maxn];
    int np, prime[maxn];
    
    void generate2(int n)
    {
        // 这里的i就是上述讨论中的C
        for(int i = 2; i <= n; ++i) {
            if(!composite[i]) prime[np++] = i;
            for(int j = 0; j<np && i*prime[j]<=n; ++j) {
                composite[i*prime[j]] = 1;
                // 为什么在这里break,类比完全背包思考一下 (^_^)
                if(i % prime[j] == 0) break;
            }
        }
        for(int i = 0; i < np; ++i)
            printf("%d ", prime[i]);
        putchar('\n');
    }
    
  • 相关阅读:
    Django框架13 /缓存、信号、django的读写分离
    linux09 /消息队列、saltstack工具
    会话管理之AbpSession
    ABP之事件总线(5)
    依赖注入容器之Castle Windsor
    ABP之事件总线(4)
    ABP之事件总线(3)
    ABP之事件总线(2)
    ABP之事件总线(1)
    ABP之展现层(Datatables分页)
  • 原文地址:https://www.cnblogs.com/sequix/p/8524770.html
Copyright © 2020-2023  润新知