zoukankan      html  css  js  c++  java
  • 素数

              素数

        素数,又叫质数,定义是除了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

  • 相关阅读:
    搜索rapidshare资源的几种方法
    Sharepoint 浅谈 [转]
    如何使用本地账户“完整”安装 SharePoint Server 2010
    为SharePoint 2010配置基于表单的身份认证
    网页禁用右键、防拷贝及"另存为"失效方法
    Sharepoint 2010 表单 身份认证(基于SQL数据库)
    SharePoint2007文档的点击率统计
    Sharepoint2010 表单认证常见问题
    sharepoint不能上载多个文件
    关于android service 重启
  • 原文地址:https://www.cnblogs.com/v-vip/p/9246386.html
Copyright © 2011-2022 走看看