POJ2689 Prime Distance 区间筛素数

The branch of mathematics called number theory is about properties of numbers. One of the areas that has captured the interest of number theoreticians for thousands of years is the question of primality. A prime number is a number that is has no proper factors (it is only evenly divisible by 1 and itself). The first prime numbers are 2,3,5,7 but they quickly become less frequent. One of the interesting questions is how dense they are in various ranges. Adjacent primes are two numbers that are both primes, but there are no other prime numbers between the adjacent primes. For example, 2,3 are the only adjacent primes that are also adjacent numbers.
Your program is given 2 numbers: L and U (1<=L<
U<=2,147,483,647), and you are to find the two adjacent primes C1 and
C2 (L<=C1< C2<=U) that are closest (i.e. C2-C1 is the
minimum). If there are other pairs that are the same distance apart, use
the first pair. You are also to find the two adjacent primes D1 and D2
(L<=D1< D2<=U) where D1 and D2 are as distant from each other
as possible (again choosing the first pair if there is a tie).

Input

Each line of input will contain two positive integers, L and U,
with L < U. The difference between L and U will not exceed 1,000,000.

Output

For each L and U, the output will either be the statement that
there are no adjacent primes (because there are less than two primes
between the two given numbers) or a line giving the two pairs of
adjacent primes.

Sample Input

2 17
14 17

Sample Output

2,3 are closest, 7,11 are most distant.
There are no adjacent primes.
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
typedef long long ll;
const int maxn = 1000005;
bool is_prime[maxn];
bool is_prime_small[maxn];
ll prime[maxn];
ll prime_num=0;

//对区间[a,b)内的整数执行筛法,is_prime[i-a]=true  ---  表示i是素数 注意这里下标偏移了a,所以从0开始。
void segment_sieve(ll a,ll b) {
    for(ll i=0;i*i<=b;++i) is_prime_small[i]=true; //对[2,sqrt(b))的初始化全为质数
    for(ll i=0;i<=b-a;++i) is_prime[i]=true; //对下标偏移后的[a,b)进行初始化

    for(ll i=2;i*i<=b;++i) {
        if(is_prime_small[i]) {
            for(ll j=2*i;j*j<=b;j+=i) is_prime_small[j]=false;  //筛选[2,sqrt(b));
            //(a+i-1)/i得到最接近a的i的倍数,最低是i的2倍,然后筛选
            for(ll j=max(2LL,(a+i-1)/i)*i;j<=b;j+=i) is_prime[j-a]=false;
        }
    }
    for(ll i=0;i<=b-a;++i)  //统计个数
        if(is_prime[i]) prime[prime_num++]=i+a;
}

int main()
{
    ll a,b,ans1,ans2,ans3,ans4,dis1,dis2;
    while(~scanf("%lld%lld",&a,&b))
    {
        if(a==1)
            a++;
        prime_num=0;
        dis1 = 0;
        dis2 =  1000010;
        memset(prime,0,sizeof(prime));
        segment_sieve(a,b);
        for(ll i=1;i<prime_num;++i)
        {
            //printf("%d",prime[i]);
            if(prime[i]-prime[i-1]>dis1)
            {
                dis1 = prime[i]-prime[i-1];
                ans1 = prime[i-1];
                ans2 = prime[i];
            }
            if(prime[i]-prime[i-1]<dis2)
            {
                dis2 = prime[i]-prime[i-1];
                ans3 = prime[i-1];
                ans4 = prime[i];
            }
        }
        //cout<<prime_num<<endl;
        if(dis1==0)
            printf("There are no adjacent primes.\n");
        else
            printf("%lld,%lld are closest, %lld,%lld are most distant.\n",ans3,ans4,ans1,ans2);
        //printf("%lld\n",prime_num);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/--lr/p/8350653.html

时间: 2024-10-29 02:48:04

POJ2689 Prime Distance 区间筛素数的相关文章

POJ-2689 Prime Distance (两重筛素数,区间平移)

Prime Distance Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 13961   Accepted: 3725 Description The branch of mathematics called number theory is about properties of numbers. One of the areas that has captured the interest of number th

poj 2689 Prime Distance(大区间筛素数)

http://poj.org/problem?id=2689 题意:给出一个大区间[L,U],分别求出该区间内连续的相差最小和相差最大的素数对. 因为L<U<=2147483647,直接筛素数是不行的,数组就开不了.但是可以根据素数筛的原理.我们先筛出sqrt(2147483647)以内的素数,然后拿这些素数去筛[L,U]之间的素数,即两次素数筛.但是L,U还是很大,但U-L<=1000000,所以进行区间平移,将[L,U]平移为[0,U-L],就能用数组放得下. #include &l

POJ2689 Prime Distance(数论:素数筛选)

题目链接:传送门 题目: Prime Distance Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 24073 Accepted: 6306 Description The branch of mathematics called number theory is about properties of numbers. One of the areas that has captured the interest of

POJ-2689 Prime Distance(线性筛法)

Prime Distance Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 17021   Accepted: 4536 Description The branch of mathematics called number theory is about properties of numbers. One of the areas that has captured the interest of number th

POJ 2689 - Prime Distance - [筛法求素数]

题目链接:http://poj.org/problem?id=2689 Time Limit: 1000MS Memory Limit: 65536K Description The branch of mathematics called number theory is about properties of numbers. One of the areas that has captured the interest of number theoreticians for thousan

POJ2689 Prime Distance

题意:输入[l,r]代表,问区间里面最近和最远的两个素数(0<l<r<int_max, r-l<100000) 题解:素数筛,一个数是合数,那么它存在小于sqrt(n)的素因子,找到所有小于sqrt(int_max)的素数,注意数据:1 2 #include <iostream> #include <string.h> #include <stdio.h> #define N 1001000 #define ll long long using

九度OJ 1040 Prime Number (筛素数,试除法)

题目描述: Output the k-th prime number. 输入: k≤10000 输出: The k-th prime number. 样例输入: 3 7 样例输出: 5 17 这道题,好久以前使用试除法做的,原理是维护一个素数表,根据输入的num,确定是否之前算过,算过了,就直接输出,没算过,就现在开始算,并且把中间的素数全保存下来: #include<stdio.h> int k[10001]; int main(int argc, char *argv[]) { k[1]=

poj 2689 区间筛素数

由于区间的右端点非常大(INT_MAX),而区间长度相对小(100W),所以考虑区间筛法,左端点为1的情况需要特判一下. 1 #include <cstring> 2 #include <cstdio> 3 #include <cmath> 4 using namespace std; 5 6 typedef long long ll; 7 const int MAX = 9999999; 8 const int MIN = -1; 9 const int N = 50

[题解](区间质数筛)POJ_2689 Prime Distance

区间筛素数:先筛出1~sqrt(R)的素数,然后对于每个询问只要用这些素数筛掉区间内的合数即可. 几个细节:1.特判和1有关的一些情况 2.每次减去L偏移量,数组只开区间大小 3.POJ无法使用万能头文件(需要火星救援(大雾 #include<iostream> #include<cstdio> #include<cstring> using namespace std; int prime[50009]; bool ck[1000009],tmp[1000009];