素数筛法就像这样

void calprime(){
long long i,j;
memset(vis,
0,sizeof(vis));
priLen
= 0;
for(i = 2; i <= M; i++)
if(!vis[i]){
prime[priLen
++] = i;
for(j = i*i; j <=M; j+=i)
vis[j]
= 1;
}
}

而双次筛法可以判断一个区间,假设区间为[k,m]只要先用筛法计算出2到sqrt(m)间的素数,然后用同方法计算k到m区间的就可以了

ac——code

#include <iostream>
using namespace std;
#define M 46342
#define _mAX 1000004
long long prime[M];
int priLen;
int vis[M];
int vis2[_mAX];
int prime2[_mAX];
int priLen2;
int nvis[_mAX];
void calprime(){
long long i,j;
memset(vis,
0,sizeof(vis));
priLen
= 0;
for(i = 2; i <= M; i++)
if(!vis[i]){
prime[priLen
++] = i;
for(j = i*i; j <=M; j+=i)
vis[j]
= 1;
}
}
void duoPrime(int l,int r){
int base,i,t;
unsigned
int j;
priLen2
= 0;
if(l < 2)
l
= 2;
base = l;
memset(vis2,
0,sizeof(vis2));
memset(prime2,
0,sizeof(prime2));
for(i = 0; i < priLen && prime[i]*prime[i] <= r ; i++){
if(prime[i]*prime[i] >= l)
j
= prime[i];
else if(l / prime[i]*prime[i] == l)
j
= l / prime[i];
else j = (l/prime[i]+1);
for(j = j*prime[i];j <=r; j+=prime[i]){
vis2[j
-base]=1;
}
}
}
void find(int l,int r){
int _min,_max,_pre,t,s1,s2,s3,s4;
unsigned
int i;
_min
= INT_MAX;
_max
= -1;
_pre
= -1;
if(l < 2)
l
=2;
for(i = l; i <= r;i++ ){
if(vis2[i - l] == 0){
if(_pre == -1){
_pre
= i;
continue;
}
else {
t
= i - _pre;
if(t > _max){
_max
= t;
s1
= _pre;
s2
= i;
}
if(t < _min){
_min
= t;
s3
= _pre;
s4
= i;
}
_pre
= i;
}
}
}
if(_min == INT_MAX)
puts(
"There are no adjacent primes.");
else printf("%d,%d are closest, %d,%d are most distant.\n",s3,s4,s1,s2);
}
int main(){
int l,u;
calprime();
while(scanf("%d%d",&l,&u)!=EOF){
duoPrime(l,u);
find(l,u);
}
return 0;
}