• 素数


    学数论 心情复杂 没什么好说的 , , ,, z h 大佬!!


    素数

    定义

    就是质数 , ( 1不是素数) , 一个比 1 大的整数若没有约数(1不算) , 称为合数

    整除

    (a=kd) ( (k) 为整数) , 则称 (d) 整除 (a) , 记做 (d)

    素数计数函数

    小于/等于 (x) 的素数的个数 , 用 (pi(x)) 表示 , 随着 (x) 的增大 , 有这样的近似结果 :

    [pi(x) sim frac{x}{ln(x)} ]

    素数筛法

    (LARGE暴力) (O(nsqrt n))

    对于检验一个数是不是素数 , 暴力做法 --- 枚举 ,, 稳妥 , 但没必要 , 显然 , 若 (x)(a) 的约数 , 那么 (frac{a}{x}) 也是 (a) 的约数 , 所以对于每对 ((x, frac ax)) , 只需检验其中一个就可以了 , 其中较小的那个约数在区间 ([1,sqrt a]) 里 , 故单次判断的时间复杂度为

    bool isPrime(a) {
        if(a < 2) return 0; // 1是约数
        for(int i = 2; i * i <= a; i ++) 
            if(a % i == 0) return 0;
        return 1;
    }
    

    (LARGEmathfrak{Eratosthenes} 筛法 (埃拉托斯特尼筛法 / 埃氏筛)) (O(n~log~log~n))

    考虑到对于合数 (x) , (x) 的倍数一定也是合数 , 从小到大筛 , 顺手把当前数的倍数标记为合数 , 最后没被标记 (tag[i] = 1) 的数为素数 , 并且都存到了 (prime) 数组里

    void Eratosthenes(int n) { 
        int p = 0;
        for(int i = 0; i <= n; i ++) tag[i] = 1;
        tag[0] = tag[1] = 0; //以上为初始化标记
        for(int i = 2; i <= n; i ++) {
            if(tag[i]) {
                prime[p ++] = i; //p为当前素数数量
                for(int j = i * i; j <= n; j += i) tag[j] = 0; 
                //已经筛过了2到i-1的倍数,所以直接从i开始
            } 
        }//需要返回质数个数的话写成int的函数 return p 即可
    }
    

    (LARGEmathfrak{Euler} 筛法 (欧拉筛/线性筛)) (O(n))

    考虑到埃氏筛把一些合数重复筛到 , 所以还不够优 , 在埃氏筛的基础上,欧拉筛思想为:每个合数只被它的最小质因子筛到一次

    int pri[maxx], tag[maxx];
    void Euler(int maxx) {
        int cnt(0);
        for(int i = 2; i <= maxx; i ++) {
            if(!tag[i]) pri[++ cnt] = i;
            for(int j = 1; j <= cnt, i * pri[j] <= maxx; j ++) {
    	    tag[i * pri[j]] = 1;
                if(i % pri[j] == 0) break;
            }
        }
    }
    

    end.

    而我们终其一生,都希望能成为更好的人。
  • 相关阅读:
    点击弹出层以外的区域隐藏弹出层
    css3 animation 动画属性简介
    IdentityServer4 接入自己的用户体系
    分布式事务的实现
    微服务分布式数据管理的挑战
    微服务的数据自治
    SkyWalking 分布式追踪系统
    创建、改进和控制微服务API的版本和契约
    富领域模型和贫血领域模型
    cenos 安装git
  • 原文地址:https://www.cnblogs.com/moziii/p/13281462.html
Copyright © 2020-2023  润新知