• 素数筛模板


      素数筛即埃氏筛法,找出小于等于给定数的所有素数个数。

    大致思路就是空间换时间:首先建立数组将所有数设为true,从2开始,因为2为true,所以2为素数,然后将2的所有倍数设为false;再对3进行相同判定,以此类推。

     1  int prime[Max_N];    //第i个素数 
     2  bool is_prime[MAX_N + 1];    //is_prime[i]为true表示i是素数
     3  
     4  int sieve(int n){
     5      int p = 0;
     6      for(int i=0;i<=n;i++)    is_prime[i] = true;
     7      for(int i=2;i<=n;i++) {
     8          if(is_prime[i]) {
     9              prime[p++] = i;
    10              for(int j=2*i;j<=n;j+=i)    is_prime[j] = false;
    11          }
    12      }
    13      return p;
    14  } 

      然后进阶的就是欧拉筛,即给定一个区间[a,b),找出区间内所有素数个数。

      在前面的素数筛中,若循环中一个较大的素数x,开始筛他的倍数时,2x因为是2的倍数,所以已经在x=2时筛掉了;3x是3的倍数,也已经在x=3时筛掉了……。因此x需要筛掉的就只是x2之后的数。因此循环条件可以缩小至0~√b 即可。

      这里我设置了两个数组,一个表示a~b之间的数,一个表示0~√b 之间的数。

     1  typedef long long ll;
     2  
     3  bool is_prime[MAX_L];    //is_prime[i-a] = true,则i是素数 
     4  bool is_prime_small[MAX_SORT_B];
     5  
     6  void segment_sieve(ll a,ll b) {
     7      for(int i = 0; (ll)i*i < b; i++)    is_prime_small[i] = true;
     8      for(int i = 0; i < b - a; i++)    is_prime[i] = true; 
     9      
    10      for(int i = 2; (ll)i*i < b; i++) {
    11          if(is_prime_small[i]){
    12              for(int j = 2*i; (ll)j*j<b; j+=i)    is_prime_small[j] = false;
    13              for(ll j = max(2LL,(a + i - 1) / i) * i; j < b; j += i)    is_prime[j - a] = false;
    14          }
    15      }
    16  }
  • 相关阅读:
    你要结婚了丶
    20150806这是个悲伤的日子。
    今天是我的生日。
    这是从word发的第一篇博客。
    【关于JavaScript】自动计算的实例
    【关于JavaScript】常见表单用户名、密码不能为空
    【关于php】Appserv中关于DW配置站点问题
    【关于php】Appserv的安装注意事项
    【无题】写在5月18日
    HTML中如何添加日历插件(JQUERY)
  • 原文地址:https://www.cnblogs.com/ShadowCharle/p/11545401.html
Copyright © 2020-2023  润新知