POJ2689 筛素数 xingxing在努力

  此题就是让你筛选出[l, u]的素数,由于u最大是2^32次方, 所以我们只需要筛出[l, u]的合数即可求出素数。。u的最大质因数不超过2^16次方因此我们求出1-2^16的质数然后筛出l, u的合数即可。。(注意1既不是合数也不是质数),代码如下:

 

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <iostream>

using namespace std;
const int maxn = 66000 + 10;
typedef long long ll;

int vis[maxn], primes[maxn], num;
void GetPrime(int n)
{
    memset(vis, 0, sizeof(vis));
    int m = sqrt(n + 0.5);
    for(int i=2; i<=m; i++) if(!vis[i])
    for(int j=i*i; j<=n; j+=i) vis[j] = 1;
    num = 0;
    for(int i=2; i<=n; i++) if(vis[i]==0)
        primes[num++] = i;
}

bool vs[1000000 + 10];
ll  prime[1000000 + 10], nm;

void shai(ll l, ll u)
{
    if(l == 1) l++;
    memset(vs, 0, sizeof(vs));
    ll m = sqrt(u+0.5);
    for(ll a=0; a<num; a++)
    {
        ll i = primes[a];
        if(i > m) break;
        ll s;
        if(i >= l) s = 2*i;
        else //i<l
        {
            if(l%i==0) s=l;
            else s=(l/i+1)*i;
        }
        for(ll j=s; j<=u; j+=i) vs[j-l] = 1;
    }
    nm = 0;
    for(ll i=0; i<=u-l; i++) if(!vs[i])
        prime[nm++] = i+l;
}

int main()
{
    GetPrime(66000);
    int l, u;
    while(cin>>l>>u)
    {
        shai(l, u);
        if(nm == 0||nm==1)
            printf("There are no adjacent primes.\n");
        else
        {
            ll cloa=0, clob=100000000, difa=1, difb=1;
            for(int i=1; i<nm; i++)
            {
                if(prime[i]-prime[i-1]<clob-cloa)
                    cloa=prime[i-1], clob=prime[i];
                if(prime[i]-prime[i-1]>difb-difa)
                    difa=prime[i-1], difb=prime[i];
            }
            printf("%I64d,%I64d are closest, %I64d,%I64d are most distant.\n", cloa, clob, difa, difb);
        }
    }
    return 0;
}

 

posted @ 2015-11-06 12:44  xing-xing  阅读(127)  评论(0)    收藏  举报