和1~n范围内筛素数差不多...只不过对于每个素数加了一个偏移量了..比如在5 10这个区间..筛掉2的倍数..那么从6开始剔除...由于题目所给的数据..最大的合数..其质因子不会大于10^5..所以先用传统的筛素数法把1~10^5内的素数找出..然后再来筛[L,U]这个区间的素数...
Program:
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<algorithm>
#define ll long long
#define oo 1000000007
#define pi acos(-1.0)
#define MAXN 1000005
using namespace std;
ll Prime[MAXN],ans[MAXN];
int Pnum,anum;
bool P[MAXN];
void PreWork()
{
int i,x;
memset(P,true,sizeof(P));
for (Pnum=0,i=2;i<=100000;i++)
if (P[i])
for (Prime[++Pnum]=i,x=i*2;x<=100000;x+=i)
P[x]=false;
}
int main()
{
PreWork();
for (ll L,U;~scanf("%I64d%I64d",&L,&U);)
{
ll n=U-L;
memset(P,true,sizeof(P));
for (int i=1;i<=Pnum;i++)
{
ll h=Prime[i],x;
if (h*h>U) break;
x=(h-(L%h))%h;
if (L+x==h) x+=h;
for (;x<=n;x+=h) P[x]=false;
}
if (L==1) P[0]=false;
anum=0;
for (int i=0;i<=n;i++)
if (P[i]) ans[++anum]=i+L;
if (anum<2) printf("There are no adjacent primes.\n");
else
{
int i,a,b;
a=b=1;
for (i=1;i<anum;i++)
{
if (ans[i+1]-ans[i]<ans[a+1]-ans[a]) a=i;
if (ans[i+1]-ans[i]>ans[b+1]-ans[b]) b=i;
}
printf("%I64d,%I64d are closest, %I64d,%I64d are most distant.\n",ans[a],ans[a+1],ans[b],ans[b+1]);
}
}
return 0;
}