2 条题解
-
0
只要用到 ≤√R 的所有素数去“打”区间 [L,R] 上的倍数,就能把所有合数都筛掉,原因在于:
任何落在 [L,R] 中的合数 N,都至少有一个不大于 √N ≤ √R 的质因子。
证明很简单:
- 若 N 是合数,则存在整数 a,b>1,使 N=a·b。
- 如果 both a>√R 且 b>√R,那么 a·b>√R·√R=R,与 N≤R 矛盾。
- 因此,a 或 b(至少一个因子)必须 ≤√R。
这意味着:
- 我们只需先在 [2,√R] 上用普通埃拉托色尼筛出所有小素数 P。
- 再用这些 P 去把 [L,R] 上能被它们整除的数全部标记为合数,剩下的就是质数。
不用管更大的素数,因为任何由它们构成的合数,早就被它所对应的“较小”因子给标记掉了。
-
0
下面是一份面向学生的、较为系统的解题思路梳理,包含问题分析、朴素思路的不足、核心技巧(分段筛法),以及如何在实践中一步步实现。
一、题目归纳
-
输入:多组询问,每组给定两个整数 ,满足
-
任务:在闭区间 内找出:
- 最“紧邻” 的一对相邻质数(差值最小),以及它们的差值;
- 最“远隔” 的一对相邻质数(差值最大),以及它们的差值;
- 如果区间内质数不足两枚,输出 “There are no adjacent primes.”。
-
输出格式(对每组输入):
-
存在相邻质数时:
p1,p2 are closest, q1,q2 are most distant.其中 差最小, 差最大;若并列,取区间中先出现的那对。
-
否则:
There are no adjacent primes.
-
二、朴素思路及其瓶颈
-
直接判每个数是质数 对 中的每个整数 ,做一次 的 trial division 判素数,记录所有质数,再线性扫描相邻对。
- 最坏情况下区间长度可达 ,每次判 级别,复杂度约 量级,会超时。
-
预先筛到 用普通 Eratosthenes 筛到全区间的上限,比如 ?不现实,内存和时间都爆掉。
因此,需要对「大区间但相对较短」(长度 )做高效判素,这正是**分段筛法(Segmented Sieve)**的典型应用场景。
三、分段筛法核心思想
-
先对 范围内的质数做一次普通筛(上限约 )
- 用经典 Eratosthenes 筛出所有小于等于 的质数,记为列表
smallPrimes[]。
- 用经典 Eratosthenes 筛出所有小于等于 的质数,记为列表
-
对区间 “分段”标记
-
申请长度为 的布尔数组
isPrimeSegment[i](初始化都设为true), -
对于
smallPrimes[k]中的每个素数 ,将它在 上的倍数都标记为合数:- 找到区间内第一个不小于 的 的倍数 ,
- 然后步长 标记:
for (j = start; j <= R; j += p) isPrimeSegment[j-L] = false;
-
特别地,如果 ,要把
isPrimeSegment[0]设为false,因为 1 不是质数。
-
-
筛完以后, 内剩下的
true即为质数。-
依次扫描
isPrimeSegment,用一个变量prevPrime记住上一个遇到的质数, -
每遇到一个新质数
curPrime:- 如果
prevPrime有意义,就计算差值d = curPrime - prevPrime; - 检查并更新「最小差」和「最大差」对应的质数对;
- 令
prevPrime = curPrime继续扫描。
- 如果
-
-
最后根据是否找到过一次「相邻质数」来输出对应格式。
五、复杂度与可行性
-
预处理:对 做一次埃氏筛,,其中 常数非常小。
-
每组查询分段筛:
-
对每个小质数 标记 次,
-
综合起来大约是
$$ \sum_{p\le\sqrt R} \frac{R-L+1}{p} \;=\;(R-L+1)\sum_{p\le\sqrt R}\frac1p \;=\;O\bigl((R-L)\log\log R\bigr). $$ -
因为 , 也才数级,足够高效。
-
-
空间: 的布尔数组,最多 大小,常数可接受。
六、教学要点
-
为什么要分段筛? 当区间上限很大但区间长度受限时,分段筛只在我们关心的那一段做筛,避免了全域筛到 的高昂开销。
-
起始标记位置
start = max(p*p, ceil(L/p)*p)的含义:- 如果 已经小于 ,应该从 开始;
- 否则从 (埃氏筛的经典起点)开始,能够确保不漏和不重复。
-
相邻质数差的统计 扫描时只保留「上一次遇到的质数」,每次新遇到就更新差值即可,节省了额外存储。
-
边界与特殊情况
- 当区间内质数数目 时,直接输出 “无相邻” 的提示;
- 注意 可能为 1,要把 1 排除掉。
-
- 1
信息
- ID
- 1075
- 时间
- 1000ms
- 内存
- 512MiB
- 难度
- 9
- 标签
- 递交数
- 16
- 已通过
- 2
- 上传者