POJ 2689 区间素数筛

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+100;
const int maxn=1e6+100;
int cnt;
bool vis[N+100];
int prime[N/10];
bool fw[maxn];
void pri()
{
    cnt=0;
    vis[0]=vis[1]=1;
    for(int i=2; i<N; i++)
    {
        if(!vis[i])
        {
            prime[cnt++]=i;
            //printf("%d ",i);
        }
        for(int j=0; j<cnt; j++)
        {
            int x=prime[j];
            if(x*i>N)
                break;
            vis[i*x]=1;
            if(i%prime[j]==0)
                break;
        }
 
    }
}
ll MAX(ll a,ll b)
{
    if(a>b)
        return a;
    return b;
}
int main()
{
    pri();
    ll l,u;
    while(scanf("%lld%lld",&l,&u)!=EOF)
    {
        memset(fw,0,sizeof(fw));
        for(int i=0; i<cnt; i++)
        {
            ll k1=ceil((l+prime[i]-1)/prime[i]),k2=floor(u/prime[i]);
            //printf("***%d %d %d\n",prime[i],k1,k2);
            for(int j=MAX(k1,2); j<=k2; j++)
            {
                fw[j*prime[i]-l]=1;
            }
        }
        if(l==1)
            fw[0]=1;
        ll minn=maxn,maxx=0;
        ll nl,nr,fl,fr;
        ll tot=-1;
        for(int i=0; i<=u-l; i++)
        {
            if(!fw[i])
            {
                if(tot>=0)
                {
                    if(i-tot>maxx)
                    {
                        maxx=i-tot;
                        fl=tot+l;
                        fr=i+l;
                    }
                    if(i-tot<minn)
                    {
                        minn=i-tot;
                        nl=tot+l;
                        nr=i+l;
                    }
                }
                tot=i;
            }
        }
        //printf("tot=%d\n",tot);
        if(maxx==0)
        {
            printf("There are no adjacent primes.\n");
            //return 0;
        }
        else
        {
            printf("%lld,%lld are closest, %lld,%lld are most distant.\n",nl,nr,fl,fr);
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值