1 条题解
-
0
题意理解
我们有一个无穷序列,它包含所有与 n 互质的正整数,并按升序排列。
题目要求我们输出这个序列中从第 k 项开始的连续 c 项。例如 n=10 时,序列是: 1, 3, 7, 9, 11, 13, 17, 19, 21, 23, 27, 29, ...
关键性质
-
周期性
与 n 互质的数在模 n 的剩余系中具有周期性。
具体来说,如果 a 与 n 互质,那么 a + n 也与 n 互质。
所以这个序列可以看作:
先列出 1..n 中与 n 互质的数(共 φ(n) 个),然后每个数 +n,+2n, ... 这样重复。 -
欧拉函数 φ(n)
φ(n) 表示 1..n 中与 n 互质的数的个数。
在长度为 n 的任意连续区间中,恰有 φ(n) 个与 n 互质的数(由周期性可得)。
核心问题
我们需要找到第 k 个与 n 互质的数,然后连续取 c 个。
如何找第 k 个?
设第 k 个与 n 互质的数为 x。
那么 1..x 中与 n 互质的数的个数 = k。于是我们可以二分 x,计算区间 [1, x] 内与 n 互质的数的个数,找到最小的 x 使得这个个数 ≥ k。
如何计算 [1, x] 中与 n 互质的数的个数?
设这个函数为
count_coprime(n, x)
。方法:容斥原理
- 对 n 做质因数分解,得到质因子列表 primes。
- 使用容斥原理计算 [1, x] 中与 n 互质的数的个数: [ \text{count} = x - \sum \left\lfloor \frac{x}{p_i} \right\rfloor + \sum \left\lfloor \frac{x}{p_i p_j} \right\rfloor - \sum \left\lfloor \frac{x}{p_i p_j p_k} \right\rfloor + \cdots ] 其中 p_i 是 n 的质因子。
因为 n ≤ 1e14,质因子个数 m 不会太多(最多 10 多个),所以容斥的复杂度 O(2^m) 是可接受的。
算法步骤
-
质因数分解 n
用试除法分解 n,得到所有质因子。 -
二分查找第 k 个互质数的位置
下界:1
上界:估计:第 k 个互质数 ≤ k * n / φ(n) + n,但更安全的是直接设上界为一个足够大的数,比如 k * 2 加上一些缓冲,或者用公式 k * (n / φ(n)) 的几倍。
二分 mid,计算 count = [1, mid] 中与 n 互质的数的个数:- 如果 count < k,下界 = mid + 1
- 否则 上界 = mid
最终下界就是第 k 个互质数。
-
输出 c 个连续互质数
从第 k 个互质数开始,逐个检查后续的数是否与 n 互质(用 gcd),输出 c 个。
但直接逐个检查可能太慢(c 最大 1e5,k 很大时可能检查很多数)。
优化:利用周期性,先找出 1..n 中所有与 n 互质的数(即一个完整周期的互质数),然后通过周期偏移生成后续的互质数。
优化输出
- 先找出 1..n 中所有与 n 互质的数,存入数组 base。
- 设第 k 个互质数是 x,它位于某个周期中:
x = base[pos] + cycle * n,
其中 cycle = (x - 1) / n,pos 是 base 中的索引。 - 然后从 pos 开始,在 base 中循环取数,每次加 n 的倍数,输出 c 个。
这样输出阶段是 O(c) 时间。
复杂度分析
- 质因数分解:O(√n),n 最大 1e14,√n = 1e7,可接受。
- 二分查找:O(log(k * n) * 2^m),m 是质因子个数,很小。
- 输出:O(c) 或 O(φ(n))。
举例验证
n=10, k=3, c=4
- 与 10 互质的 base = [1, 3, 7, 9](φ(10)=4)
- 二分找第 3 个互质数:
- [1,1] 有 1 个互质数 <3
- [1,5] 有 2 个互质数 <3
- [1,7] 有 3 个互质数 ≥3 → 第 3 个是 7
- 从 7 开始取 4 个:7, 9, 11(=1+10), 13(=3+10)
输出:7 9 11 13
总结
这道题结合了数论(欧拉函数、互质、容斥)与二分查找,并利用周期性优化输出,是一道综合性较强的题目。
关键点在于快速计算前 x 个数中与 n 互质的数的个数,以及高效生成互质数序列。 -
- 1
信息
- ID
- 3318
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者