质数距离

质数距离

在这里插入图片描述

输入样例:
2 17
14 17
输出样例:
2,3 are closest, 7,11 are most distant.
There are no adjacent primes.
解题思路:

​ 我们无法预处理 1 < n < 2 31 − 1 1 \lt n \lt 2^{31} - 1 1<n<2311 的所有质数。对于一个数 n , 最多存在一个大于 x \sqrt x x 的质因数。所以我们可以预先处理不超过 x \sqrt x x 的质数,然后筛除 [L,U] 之间的合数。

2 31 ≈ 46340 \sqrt {2^{31}} \approx 46340 231 46340 是可以用线性筛法筛出的

预处理完primes数组后 , 我们用primes数组中的素数筛掉 [L,U] 之间的合数, 对于每一个素数primes[i] , 最先筛掉的应该是 L / p r i m e s [ i ] L / primes[i] L/primes[i] 倍的 primes[i] , 当然 要注意到两种特殊情况

  1. primes[i] == L
  2. primes[i] > L

j = L / p r i m e s [ i ] j = L / primes[i] j=L/primes[i] 对于情况 1 , j = 0 j = 0 j=0 , 对于情况2 , j = 1 j = 1 j=1

出现这两种状况时若对此时的 j × p r i m e s [ j ] j \times primes[j] j×primes[j] 标记则会出现错误

因为 L 和 U 的插值不超过 1 0 6 10^6 106 我们可以将每个 [L,U] 的数映射到下标为 [0,U-L] 的数组中 , 遍历数组即可得到答案

AC代码:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std; 
typedef long long LL;
const int inf = 0x3f3f3f3f ; 
const int N = 1e6 + 10 , M = 46350  ;
int d[N] ; 
LL primes[M] , st[M] , cnt ; 
void get_primes(){
    for(LL i = 2; i < M ; i ++ ) {
        if(!st[i]) primes[cnt++] = i ; 
        for(LL j = 0 ; j < cnt && primes[j] < M / i ; j ++ ) {
            st[ primes[j] * i ] = 1 ; 
            if( i % primes[j] == 0 ) break ;
        }
    }
}


int main(){
    int l , r ; 
    get_primes() ;
    while(~scanf("%d%d",&l,&r)){
        memset(d,0,sizeof(d)) ;
        for(LL i = 0 ; i < cnt ; i ++ ) { //筛除[L,U]中的合数
            for(LL j = l / primes[i] ; primes[i] * j <= r  ; j ++ ) {
                if( j == 0 || j == 1 ) continue ; 
                if(primes[i] * j >= l )
                    d[primes[i] * j - l ] = 1; 
            }
        }
        if(l == 1) d[0] = 1 ; //特殊处理L == 1 的情况 
        LL cnt2 = 0 , resmax = -inf , resmin = inf ;
        LL pre , th ; 
        pre = th = -1 ;
        LL resminl , resminr , resmaxl , resmaxr ; 
        for(LL i = l ; i <= r ; i ++ ) { //遍历求答案 
            if(!d[i-l]) {
                cnt2 ++ ;
                pre = th ;
                th = i ; 
                if(pre != -1 && th != -1 ) {
                    if( th - pre > resmax){
                        resmaxl = pre , resmaxr = th ; 
                        resmax = th - pre ;
                    }
                    if( th - pre < resmin ){
                        resminl = pre , resminr = th ; 
                        resmin = th - pre ;
                    }
                } 
            }
        }
        if(cnt2 < 2 ) puts("There are no adjacent primes.") ; 
        else printf("%d,%d are closest, %d,%d are most distant.\n",resminl,resminr,resmaxl,resmaxr) ; 
    }
    return 0 ; 
}
OJ:

196. 质数距离 - AcWing题库

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值