zoukankan      html  css  js  c++  java
  • 筛法复习

    首先考虑筛素数, 朴素的判断素数复杂度 (O(sqrt n))

    埃氏筛

    前几天做 mit6.s081 lab 的时候看到的, 其实就是埃氏筛法

    p = get a number from left neighbor
    print p
    loop:
        n = get a number from left neighbor
        if (p does not divide n)
            send n to right neighbor
    

    image-20210913154718594

    正确性是比较显然的,每一次 print 出来的数, 都是经过了比其小的素数的筛选, 说明其没有别的质因数。

    for(int i = 2;i < N;i++){
        if(isprime[i]){
          	for(int j = 2 * i;j < N;j += i) isprime[j] = false; // 可以从 i*i 开始枚举
        }
    }
    

    调和级数 log 复杂度, 复杂度是 (O(nlogn))

    线性筛

    void init(){
        for(int i = 2;i < N;i++){
            if(!vis[i]) prime[++cnt] = i;
            for(int j = 1;j <= cnt && prime[j] * i < N;j++){
                vis[i * prime[j]] = 1;
                if(i % prime[j]) break;
            }
        }
    }
    

    可以把理解的重点放到 if(i % prime[j]) break;

    对于每一个数 i​ , 都会用小于等于其最小质因数的素数 prime[j]​ ,把 i * prime[j] 筛去

    对于每一个合数, 都会被其最小质因数筛去, 例如考虑

    (n = p_1^{k_1}p_2^{k_2}...p_m^{k_m}) , 它肯定会被 (p_1) 筛去,并且只会被 (p_1)​​ 筛去

    考虑它被 (p_2) 筛去, 则 prime[j] = p2 , i = n / p2

    在枚举 j 的时候, 枚举到 (p_1) 的时候就 break 出去了,所以不会被 (p_2) 筛去, 其余同理

    因而其复杂度是 (O(n))​ , 是一种很优秀的筛法, 并且是一种筛积性函数的通用筛法

  • 相关阅读:
    js实现粘贴板复制
    oracle分页查询
    [小技巧]window10删除此电脑左侧栏中的非磁盘文件夹
    [web]2019第一起数据泄露事件
    [xml]AttributeError: 'xml.etree.ElementTree.Element' object has no attribute 'getroot'
    [python]Mongodb
    [urllib]urlretrieve在python3
    [flask]邮件配置-20171227
    [PowerShell]Python虚拟环境激活失败
    [git]git入门
  • 原文地址:https://www.cnblogs.com/sduwh/p/15266057.html
Copyright © 2011-2022 走看看