给定整数a、b,求区间[a,b)内有多少个素数
b以内的合数的最小质因数一定不超过√b。如果有√b以内的素数表,就可以把埃式筛法用到区间[a,b)上了。也就是说,先做好[2,√b)和[a,b)的表,然后从[2,√b)表中筛选素数的同时,也将其倍数从[a,b)的表中划去,最后剩下的就是[a,b)内的素数了。
typedef long long ll;
bool is_prime[1000000+5];
bool is_prime_small[1000000+5];
//对区间[a,b)内的整数执行筛法。is_prime[i-a]=true→i是素数
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[i]=false;//筛[2,√b)
for(ll j=max(2ll,(a+i-1)/i)*i;j<b;j+=i) is_prime[j-a]=false;//筛[a,b)
//2LL是2的长整数形式
//((a+i-1)/i)*i是满足>=a&&%i==0的离a最近的数
//也可以写成(a%i==0)?a:(a/i+1)*i
}
}
}