大区间素数查找。
因为给出的数据范围太大,无法开到那么大的数组,所以不可以一开始预处理出所有的素数。
又因为l和u之间的差值最大1e6,所以也不可能一个一个地去判断。
正确的方法时,先预处理出 sqrt(N)范围内的全部素数,那么就可以通过这些素数来判断1~N内的所有数是素数还是合数。
对于给定的区间[l,u],利用埃氏筛的思想,选择相应的素数,把给定区间的素数的倍数给去除。又考虑到数据范围,可以把l[l,u]内的数全部都减小l来存入标记。
最后只要统计一下,剩下的素数的个数,并找到目标解,即可。
一个注意的地方就是,利用埃氏筛的思想进行筛选时,用累加。

#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
typedef long long ll;
const ll N=2147483650;
const ll inf=0x3f3f3f3f;
const int MAXN=1e6+5;
const int M=46350;
bool vis[M];
bool book[MAXN];
vector<int>prime;
ll l,u;
void oula()
{
    memset(vis,false,sizeof(vis));
    prime.clear();
    for(int i=2;i<M;i++)
    {
        if(!vis[i])
            prime.push_back(i);
        for(int j=0;j<prime.size()&&i*prime[j]<M;j++)
        {
            vis[i*prime[j]]=true;
            if(i%prime[j]==0)
                break;
        }
    }
}
void solve()
{
    for(ll i=0;i<=u-l;i++)
        book[i]=true;
    for(int i=0;i<prime.size()&&prime[i]<=u;i++)
    {
        ll num=l/(ll)prime[i];
        ll w=num*prime[i];
        while(w<l||w==prime[i])
            w+=prime[i];
        for(ll j=w;j<=u;j+=prime[i])//用加法,不用用乘法,否则超时
        {
            if(j>=l)
               book[j-l]=false;
        }
    }
}
int main()
{
    oula();
    while(scanf("%lld%lld",&l,&u)!=EOF)
    {
        int cnt=0;
        ll a=0,b=0,c=0,d=0,minn=inf,maxn=0,t=0;
        solve();
        for(int i=0;i<=u-l;i++)
        {
            if(book[i]&&i+l>1)
            {
                cnt++;
                if(cnt>=2)
                {
                    if(i+l-t<minn)
                    {
                        a=t;
                        b=i+l;
                        minn=i+l-t;
                    }
                    if(i+l-t>maxn)
                    {
                        c=t;
                        d=i+l;
                        maxn=i+l-t;
                    }
                }
                t=i+l;
            }
        }
        if(cnt<2)
            printf("There are no adjacent primes.\n");
        else
            printf("%lld,%lld are closest, %lld,%lld are most distant.\n",a,b,c,d);
    }
    return 0;
}