POJ 2689 Prime Distance(素数区间筛法--经典题)

来源:互联网 发布:酷开电视直播软件 编辑:程序博客网 时间:2024/05/22 14:34

大致题意:给定[L,R]区间,找出区间内的每个素数

数据范围 :

1<=L< R<=2,147,483,647)

R-L <=1,000,000.

R的数值太大,所以不能直接筛[0,R]的,要空间和时间优化,用到区间筛法,另外注意不能用int,因为R和L都是满int的,中间有很多细节处理会爆int的,还要注意1不是素数,所以在区间筛中要特判一下,是个易错的地方

//1160K16MSC++1539B#include<cstdio>#include<iostream>#include<algorithm>#include<cstring>using namespace std;const int MAXN = 1e6+1e3;   //待筛的区间[L,R]长度const int N = 50001;//保证大于(2^31-1)的算数平方根bool prime[MAXN];bool seive[N];typedef long long ll;int L,R,len;void seg_seive(ll L,ll R)   //区间筛法{    len=R-L+1;    for(int i=0;i<len;i++) prime[i]=1;    if(1-L>=0) prime[1-L]=0;   //易错因为1不是素数也不是合数,这也是区间筛的一个易错bug    for(ll i=2; i*i<=R ;i++)    {        if(seive[i])        {            for(ll j=max((ll)2,(L-1+i)/i)*i;j<=R;j+=i)  //第二个易错点,j必须从大于1,因为L可能小于i,但是seive[i]是素数。                prime[j-L]=false;        }    }}int main(){    for(int i=2;i<N;i++) seive[i]=1;    for(int i=2;i*i<N;i++)  //预处理        if(seive[i])            for(int j=2*i;j<N;j+=i)                seive[j]=false;            while(~scanf("%d%d",&L,&R))    {        seg_seive(L,R);        int lmax,rmax,lmin,rmin;        int mmax=-1,mmin=(1<<30);        int t=-1;        for(int i=0;i<len;i++)            if(prime[i])            {                if(t>=0)                {                    if(mmax<i-t) mmax=i-t,lmax=t+L,rmax=i+L;                    if(mmin>i-t) mmin=i-t,lmin=t+L,rmin=i+L;                    t=i;                }                else t=i;            }        if(mmax>0) printf("%d,%d are closest, %d,%d are most distant.\n",lmin,rmin,lmax,rmax);        else puts("There are no adjacent primes.");    }    return 0;}


0 0
原创粉丝点击