利用两次素数筛选,第一次筛选 1--500000,第二次利用第一次的结果筛选出l--r间的素数,注意如果l是1,,则筛选不出,应单独判断。最后穷举最大最小距离
#include<iostream>
#include<cstring>
using namespace std;
const int N=50001;
bool prime[N+1];
long long p[N+1],pri[1000005];
int w;
void getprime()
{
memset(prime,0,sizeof(prime));
int k=0;
for(int i=2;i<=N;i++)
{
if(!prime[i]) p[k++]=i;
for(int j=0;j<k;j++)
{
if(p[j]*i>N) break;
prime[p[j]*i]=1;
if(i%p[j]==0) break;
}
}
// cout<<k<<endl;
w=k-1;
//for(int i=0;i<10;i++) cout<<p[i]<<endl;
}
int luprime(long long l,long long r)
{ int flag=0;
long long k;
memset(pri,0,sizeof(pri));
// cout<<w<<endl;
for(int i=0;i<=w;i++)
{
// cout<<p[i]<<endl;
if(p[i]>=r) break;
k=l/p[i];
while((k*p[i])<l||k==1){
k++;
}
//cout<<k*p[i]<<endl;
for(long long j=k*p[i];j<=r;j+=p[i])
{
if(!pri[j-l])
{
pri[j-l]=1;
//cout<<j<<" "<<k<<" "<<p[i]<<endl;
flag++;
}
// cout<<flag<<endl;
}
}
if(l==1)
{
pri[0]=1;
flag++;
}
// cout<<flag<<endl;
return flag;
}
int main()
{
getprime();
long long l,u;
while(cin>>l>>u)
{
int flag;
flag=luprime(l,u);
//cout<<flag<<endl;
// for(int i=0;i<=u-l;i++)
// if(!pri[i]) cout<<i+l<<endl;
if(flag>=u-l) cout<<"There are no adjacent primes."<<endl;
else
{
long long min1,min2,min,max,max1,max2;
int i;
for(i=0;i<=u-l;i++)
{
if(!pri[i])
{
min1=max1=i;
min2=max2=i;
break;
}
}
i++;
for(i;i<=u-l;i++)
{
if(!pri[i])
{
min2=max2=i;
min=max=i-min1;
// cout<<min1<<" "<<min2<<" "<<max1<<" "<<max2<<endl;
break;
}
}
long long last=i;
i++;
for(i;i<=u-l;i++)
{
if(!pri[i])
{
if(i-last<min)
{
min=i-last;
min1=last;
min2=i;
}
if(i-last>max)
{
max=i-last;
max1=last;
max2=i;
//cout<<max1+l<<" "<<max2+l<<endl;
}
last=i;
}
}
cout<<min1+l<<","<<min2+l<<" are closest, "<<max1+l<<","<<max2+l<<" are most distant."<<endl;
}
}
}