Poj P2689 Prime Distance___线性筛素数

题目大意:

给出多个询问,每个询问给出区间[l,r],问其中相邻素数差最小的一对数是多少,差最大的一对数是多少。

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

分析:

筛除[1,根号2^31]之间的素数

然后对于每次给出的询问[l,r]

我们用素数表处理出其中的素数,注意判断一下l=1的情况,

而且注意不知道为什么,直接枚举l~r会炸,虽然只有1e6的长度…

代码:

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#define N 1000005
#define M 17


using namespace std;


int prime[1<<M],v[1<<M],a[N],cnt = 0,l,r;


void work(){
    for (int i = 2; i <= 1<<M; i++){
         if (!v[i]){
             prime[++cnt] = i;
             v[i] = i;
         }
         for (int j = 1; j <= cnt; j++){
              if (prime[j] > v[i] || prime[j]*i > 1<<M) break;
              v[prime[j]*i] = prime[j]; 
         }
    }
}


int main(){
    work();
    while (cin >> l >> r){
           memset(a, 0, sizeof(a));
           if (l == 1) l = 2;
           for (int i = 1; i <= cnt; i++){
                if (prime[i] > r) break;
                int x = prime[i];
                int a1 = (l-1)/x+1, b1 = r/x;
                if (a1 == 1) a1 = 2;
                for (int j = a1; j <= b1; j++) a[j*x-l+1] = 1;  
           }
           int x = 0, y = 0;
           int cha1 = N, min1 = 0, min2 = 0;
           int cha2 = 0, max1 = 0, max2 = 0;
           for (int i = 1; i <= r-l+1; i++)
                if (!a[i]){
                    if (!x) x = i+l-1;
                       else { 
                              y = x, x = i+l-1;
                              if (x-y < cha1) cha1 = x-y, min1 = y, min2 = x;
                              if (x-y > cha2) cha2 = x-y, max1 = y, max2 = x;
                       }
                }
           if (!min1) cout<<"There are no adjacent primes."<<endl;      
                else  cout<<min1<<","<<min2<<" are closest, "<<max1<<","<<max2<<" are most distant."<<endl;  
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/gx_man_vip/article/details/80256617
今日推荐