• 素数


              素数

        素数,又叫质数,定义是除了1和它本身以外不再有其他的因数

        根据定义,可以用以下程序来判断一个数是否为素数

    bool prime(int x) {//判断x是否为质数,时间复杂度为O(n)
        if(x <= 1) return false; 
        for(int i = 2; i < x; i ++)
            if(x % i == 0) return false;
        return true;
    }

        接下来要加速了哦

    bool prime2(int x){  //判断是否为质数,时间复杂度为O(sqrt(n)) 
        if(x <= 1) return false; 
        for(int i = 2; i <= sqrt(x + 0.5); i ++)  //0.5是防止根号的精度误差 
            if(x % i == 0) return false;
        return true;
    
        //另一种写法,可避免根号的精度误差 
        if(x <= 1) return false; 
        for(int i = 2; i * i <= x; i++)
            if(x % i == 0) return false;
        return true;
    }

        虽然已经挺快的了,但是如果 n 比较大的话就不好玩了

        so... 接下来我们要讲一种更快的算法——埃拉托斯特尼筛法(咦~,好长),那就简称埃氏筛法吧

       原理:如果找到一个质数,那么这个质数的倍数都不是质数

    void init() {  //时间复杂度O(nloglogn) 我也不知道怎么算出来的 2333
        for(int i = 2; i < N; i++) prime[i] = true;
        for(int i = 2; i * i < N; i++)
            if(prime[i])
                for(int j = i * i; j < N; j += i)  //因为之前的都判断过了,所以从i*i开始就可以了 
                    prime[j] = false;
    }
    
    int main() {
        scanf("%d", &N);
        init();
    }

        线性筛法(欧拉筛法)

      保证每个合数只会被它的最小质因数筛去,因此每个数只会被标记一次,所以时间复杂度是O(n)

    void prime() {
        for(int i = 2; i < n; i++) {
            if(!check[i]) prime[tot++] = i;
            for(int j = 0; j < tot; ++j) {
                if(i * prime[j] > n) break;
                check[i * prime[j]] = 1;
                if(i % prime[j] == 0) break;
            }
        }
    }

      基于埃式筛法的原理,我们可以用它干很多事,比如:

    #include<cstdio>
    #include<vector>
    using namespace std;
    const int N = 100000 + 5;
    vector<int> prime_factor[N];
    void init() {
        for(int i = 2; i < N; i ++)
            if(prime_factor[i].size() == 0)  //如果i是质数 
                for(int j = i; j < N; j += i)
                    prime_factor[j].push_back(i); 
    }
    int main() {
        init();
    }
    预处理每个数的所有质因数
    #include<cstdio>
    #include<vector>
    using namespace std;
    const int N = 100000 + 5;
    vector<int> factor[N];
    void init() {
        for(int i = 2; i < N; i ++)
            for(int j = i; j < N; j += i)
                factor[j].push_back(i); 
    }
    int main() {
        init();
    }
    预处理每个数的所有因数
    #include<cstdio>
    #include<vector>
    using namespace std;
    const int N = 100000 + 5;
    vector<int> prime_factor[N];
    void init() {
        int temp;
        for(int i = 2; i < N; i ++)
            if(prime_factor[i].size() == 0)
                for(int j = i; j < N; j += i){
                    temp = j;
                    while(temp % i == 0){
                        prime_factor[j].push_back(i);
                        temp /= i;
                    }  
                }
    }
    int main() {
        init();
    }
    预处理每个数的质因数分解

      推荐博客(专门讲素数的哦):https://www.cnblogs.com/grubbyskyer/p/3852421.html

  • 相关阅读:
    bzoj 1026
    mysql索引面试题
    Mybatis基础,动态sql (mybatis中的重点)
    Mybatis基础,利用mybatis实现复杂查询,多对一,一对多
    Mybatis基础:注解开发,面向接口(引出三个面向的区别)
    Mybatis基础,limit分页,和RowsBounds分页,分页插件
    Mybatis基础,日志工厂
    Mybatis基础一,生命周期,和作用域,resultMap(结果集映射)
    Mybatis配置解析三,typeAliases(别名),setting(设置)
    浅谈JPA
  • 原文地址:https://www.cnblogs.com/v-vip/p/9246386.html
Copyright © 2020-2023  润新知