素数筛代码:
int prime[MAXN];
int isprime[MAXN + 1];
int con(int n)
{
int p = 0;
for(int i = 0; i <=n; i++)
{
isprime[i] = 1;
}
isprime[0] = isprime[1] = 0;
for(int i = 2; i<=n; i++)
{
if(isprime[i])
{
prime[p++] = i;
}
for(int j = 2*i; j <= n; j = j +i)
{
isprime[j] = 0;
}
}
return p;
}
#include<cstring>
#include<cstdlib>
#include<algorithm>
#define maxa 1000000
using namespace std;
int m[maxa];
int a[maxa];
int prime()
{
int i,j;
memset(m,0,sizeof(m));
m[0] = m[1] = 1;
int cnt = 0;
for(i = 2; i <= maxa; i++)
{
if(!m[i])
{
cnt++;
{
m[i*j] = i;
}
}
}
{
int n;
{
if(n==0||n==1)
printf("1\n");
else
{
// prime();
}
}
区间筛法: a < b < 10^12
b - a < 10^6
a,b范围太大,不能直接求int范围的素数。而区间间隔比较小,只有1e6,而且对于int范围内的合数来说,最小质因子必定小于2^16。所以可以求出[a,b]中合数,转而求出素数,然后暴力枚举所有素数对即可。
如何求区间[a,b]中的合数:合数的最小质因子小于2^16,即小于50000。所以先求出小于50000的所有素数。则区间[l,u]中的合数,必定可以表示为小于50000的素数的倍数。枚举所有小于50000的素数,再找出[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
}
}
}