poj 2689 大范围素数

题意:求大区间A  B内离的最近和最远的两个素数,A B<=2,147,483,647

分析:先用大素数的线性筛法,预处理出1~sqrt(2,147,483,647)的所有素数,然后用 b[0] ~ b[B-A],来表示A+(0) ~ A+(B-A)的数是否是素数。。

即若素数p*k = A+x  -->  A+x不是素数  -->  b[x]=1 。

 

 

#define Max  2147483647
#define maxn 50000
int prime[maxn],p;
bool vis[maxn] ;
void getPrime(int n){//大范围内素数的线性筛法
    FOE(i,2,n){
        if( !vis[i])
            prime[p++] = i;
        for(int j = 0;j < p && prime[j] * i <= n; j++){
                vis[prime[j] * i] = true;
                if(i % prime[j] == 0)break;
        }
    }
}

int pri[500000],q;
bool v[1000000];
void getPri(int a,int b){//求区间a b的素数
    //prime[0~p]先存放2到sqrt(b_max)的素数
    memset(v,0,(b-a+3)*sizeof(bool)); q=0;
    for(int i = 0; prime[i]*prime[i] <= b && i < p;i++){
            long long k = a/prime[i];
            if (k*prime[i] < a) k++;
            if (k <= 1) k++;
            while(k*prime[i] <= b){
                v[k*prime[i] - a] = 1;
                k++;
            }
    }
    FOE(i,0,b-a)
        if(v[i] == 0)
            pri[q++] = a+i;
}

int L,U;
void solve(){
    int x1,x2,y1,y2;
    x1=x2=-1;   y2=Max; y1=0;
    FOR(i,1,q){
        if(x2-x1<pri[i]-pri[i-1])x1=pri[i-1],x2=pri[i];
        if(y2-y1>pri[i]-pri[i-1])y1=pri[i-1],y2=pri[i];
    }
    if(L==1){
        if(U==2) cout<<"There are no adjacent primes."<<endl;
        else if(U<5) cout<<2<<","<<3<<" are closest, "<<2<<","<<3<<" are most distant."<<endl;
        else cout<<2<<","<<3<<" are closest, "<<x1<<","<<x2<<" are most distant."<<endl;
    }else if(x1==-1)cout<<"There are no adjacent primes."<<endl;
    else cout<<y1<<","<<y2<<" are closest, "<<x1<<","<<x2<<" are most distant."<<endl;
}


int main(){
    int t=sqrt((double)Max);
    getPrime(t);
    while(cin>>L>>U){
        getPri(L,U);
        solve();
    }
    return 0;
}

 

posted @ 2013-05-29 22:33  心向往之  阅读(115)  评论(0编辑  收藏  举报