素数筛法就像这样
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;
}