zoukankan      html  css  js  c++  java
  • 素数筛模板

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

    大致思路就是空间换时间:首先建立数组将所有数设为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  }
  • 相关阅读:
    解决input获取焦点时底部菜单被顶上来问题
    JavaScript学习笔记
    JavaScript表单验证
    js 中{},[]中括号,大括号使用详解
    陀飞轮
    娱乐天空
    左右手
    软测 学习
    git 学习
    spring boot 学习
  • 原文地址:https://www.cnblogs.com/ShadowCharle/p/11545401.html
Copyright © 2011-2022 走看看