zoukankan      html  css  js  c++  java
  • 有关素数的基础算法

    之前因为各种原因没看数学相关问题,这回牛客网44练习赛打完或回头来看发现还是要看一下才行,不然有点摸不着头脑

    1.素数判定

    给定正整数n,请判断n是不是素数

    bool is_prime(ll n)
    {
        for (int i = 2; i*i <= n; i++)
            if (n%i==0) return false;
        return n!=1;
    }

    2.埃氏筛法

    给定正整数n,请问n以内有多少个素数?

    int prime[MAX_N]; //第i个素数 
    bool is_prime[MAX_N+1]; //值为true表示为素数
    
    //返回n以内的素数
    int sieve(ll n)
    {
        int p = 0;
        for (int i = 0; i <= n; i++) is_prime = true;
        //is_prime[0] = is_prime[1] = false;
        for (int i = 2; i<= n; i++) {
            if (is_prime[i]) {
                prime[p++] = i;
                for (int j = 2*i; j <= n; j += i) is_prime[j] = false;
            }    
        }
        return p;
    } 

    3.区间筛法

    给定正整数a和b,请问区间[a,b)又多少个素数?

    typedef long long ll;
    
    bool is_prime[MAX_L];
    bool is_prime_small[MAX_SORT_B];
    
    //对区间[a,b)内的整数执行筛法
    void segment_sieve(LL a,LL b)
    {
        for(int i = 0; (LL)i*i < b; i++) is_prime_small[i]=true;
        for(int i = 0; i < b-a; i++) is_prime[i]=true;
         //利用0~len代表a~b的数
        for(int i = 2; (LL)i*i < b; i++) {
            if(is_prime_small[i]) {
                for(int j = 2*i; (LL)j*j < b; j += i) is_prime_small[j]=false; //筛[2,√b)
                for(LL j=max(2LL, (a+i-1)/i)*i ; j < b; j+=i) is_prime[j - a] =false;//筛[a,b)
                //j代表素数,j-a是将a~b变为0~b-a以便数组好存储
                //2LL是2的长整形形式,与其比较意思是j最少是i的两倍
                //((a+i-1)/i)*i得出的是(>=a && %i==0)离a最近的数,这里分子上a-1是个小细节 
                //其实也可以写成a%i==0?a:(a/i+1)*i
            }
        }
    }
  • 相关阅读:
    Inter IPP 跟 Microsoft V100编译器区别
    目标描述(基于区域的描述)
    目标描述(基于边界的描述)
    目标表达(基于区域的表达)
    表达描述(基于变换的表达)
    目标表达(基于边界的表达)
    分割技术扩展
    分水岭分割算法
    借助均移确定聚类中心
    借助过度区选择阈值
  • 原文地址:https://www.cnblogs.com/wizarderror/p/10745749.html
Copyright © 2011-2022 走看看