埃氏筛法
求出小于整数n的素数个数。
int prime[MAX_N];// 存储素数
bool is_prime[MAX_N];//表示第i个数是否为素数
int sieve(int n){
int p=0;
for(int i=0;i<=n;i++) is_prime[i]=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;
}
区间筛法
求左开右闭区间[a,b)中素数的个数。
思路:先求出[2, b \sqrt b b)中素数,再从目标区间内划去这些数。
typedef long long ll;
bool is_prime[MAX_L];
bool is_prime_small[MAX_SQRT_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;
//枚举小区间里的数
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;
//筛大区间
for(ll j=max(2LL,(a+i-1)/i)*i;j<b;j+=i) is_prime[j-a]=false;
}
}
}