poj 2689(区间素数筛选)

     由于给出的L和U太大,直接打表是不可能了。但U-L<=1e6,U<1e9,可以先筛出[0,sqrt(U)]内的素数,再以此去筛[L,U]内的素数,接着求出相邻距离最短和最远的一对素数就行了,这步就简单了。

代码如下:

#include <cstdio>
#include <stack>
#include <set>
#include <iostream>
#include <string>
#include <vector>
#include <queue>
#include <functional>
#include <cstring>
#include <algorithm>
#include <cctype>
#include <string>
#include <map>
#include <iomanip>
#include <cmath>
#define LL long long
#define ULL unsigned long long
#define SZ(x) (int)x.size()
#define Lowbit(x) ((x) & (-x))
#define MP(a, b) make_pair(a, b)
#define MS(arr, num) memset(arr, num, sizeof(arr))
#define PB push_back
#define F first
#define S second
#define ROP freopen("input.txt", "r", stdin);
#define MID(a, b) (a + ((b - a) >> 1))
#define LC rt << 1, l, mid
#define RC rt << 1|1, mid + 1, r
#define LRT rt << 1
#define RRT rt << 1|1
#define BitCount(x) __builtin_popcount(x)
#define BitCountll(x) __builtin_popcountll(x)
#define LeftPos(x) 32 - __builtin_clz(x) - 1
#define LeftPosll(x) 64 - __builtin_clzll(x) - 1
const double PI = acos(-1.0);
const int INF = 0x3f3f3f3f;
using namespace std;
const double eps = 1e-8;
const int MAXN = 300 + 10;
const int MOD = 1000007;
const int M=1e6+10;
const int N=25;
typedef pair<int, int> pii;
int n;
bool p1[M],p2[M];

bool judge(LL l,LL r,LL &x1,LL &x2,LL &y1,LL &y2)
{
    LL i,j;
    LL t=(int)sqrt(r*1.0);
    MS(p1,true);
    MS(p2,true);
    p1[0]=p1[1]=false;
    for (i=2;i<=t;i++){
        if (p1[i]){
            for (j=i<<1;j<=t;j+=i) p1[j]=false;  // 筛 [0,sqrt(U)]
            for (j=max(2LL,(l+i-1)/i)*i;j<=r;j+=i) p2[j-l]=false;  // 筛 [L,U]
        }

    }
    LL a,b;

    LL maxx=-1,minn=INF;
    for (i=max(2LL,l) ;i<=r;i++){
        if (p2[i-l]) {
            a=i++; // 找到区间内第一个素数
            break;
        }
    }
    for (;i<=r;i++){
        if (p2[i-l]){
            b=i;
            if (maxx<b-a) { x1=a; y1=b; maxx=b-a; }
            if (minn>b-a) { x2=a; y2=b; minn=b-a; }
            a=b;
        }
    }
    if (maxx>0) return true;
    else return false;
}
int main()
{
    LL l,r;

    while(~scanf("%lld%lld",&l,&r))
    {
        LL x1,x2,y1,y2;
        if (judge(l,r,x1,x2,y1,y2)) printf("%lld,%lld are closest, %lld,%lld are most distant.\n",x2,y2,x1,y1);
        else puts("There are no adjacent primes.");
    }
}

/*
in:  21 45645
out: 29 31   31397  31469
*/






















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值