简要题意:
给定一个数列 (a_1 , a_2 cdots a_{n-1}),求 任意一个满足以下条件的长度为 (n) 的质数数列 ( ext{ans}):
本题是某洛谷公开赛 (T1),有一定思维难度。
前记
本人 (193ms) 的代码截止 ( ext{2020.5.5 12:00}) 排名第一,效率最高。 如果不开火车头优化就屈居第三了 (实际上估计也 不太 会有人能超过它了,除非是变态卡常)
下面的 (m) 指的是:
并且,各算法对应的数据范围没有下限是因为不存在特殊情况,特此说明。
算法一
对于 (20 \%) 的数据,(n leq 5),(m leq 10).
显然我们可以发现,如果确定了 (p_1),就可以递推出整个数列。
由于 (p_1) 只受到 (a_1) 的限制(即 (p_1 | a_1)),所以我们枚举 (a_1) 的 质因子 作为 (p_1),然后递推判断即可。
时间复杂度:(O(Tn sqrt{m}))
解释:(T) 组数据,每组数据枚举因数是 (O(sqrt{m})) 的时间,递推是 (O(n)) 的时间,而判断素数我们可以打表(反正 (20) 以内的素数也不多),(O(1)) 判断即可。
实际得分:(20pts) ~ (40pts).(下面会有说明)
注:上述代码并没有预处理素数表。(实际上浪费 (sqrt{M}) 的时间也不会有什么问题)
算法二
对于 (40 \%) 的数据,(m leq 10^{12}).
这个部分分没什么用,是用来给选手乱搞的。
出题人的官方题解中说:
(看得不太清楚可以放大看)
实际上这样理论上是无法通过 (n leq 10^5) , $T leq 5 $, (m leq 10^{12}) 这样庞大的数据。
简单计算一下:
你可以欧拉筛出 (sqrt{m} = 10^6) 以内的素数表,共 (78498) 个,估算为 (8 imes 10^4) 个。
你在这 (8 imes 10^4) 个中枚举因数,然后 (O(n)) 验证。
时间复杂度:(O(Tn imes 8 imes 10^4)).
简单估计:(O(5 imes 10^5 imes 8 imes 10^4 = 40 imes 10^9 = 4 imes 10^{10})).
所以理论上,如果跑满时间复杂度是根本无法通过的,也无法分析该程序具体的常数是多少。
可能出题人的数据有点弱,导致每次 (O(n)) 根本跑不满,枚举到半路就被剪枝了吧。
所以按照算法一的思路,卡一卡常数就可以得到 (40pts).
时间复杂度:(O(Tn sqrt{m})).
实际得分:(20pts) ~ (40pts).
算法三
对于 (70 \%) 的数据,(a_i ot = a_{i+1}).
暂时我们想不出,(a_i ot = a_{i+1}) 有什么性质。
那么先把得到的 (n-1) 个方程组列出来吧:
只看前两个方程,我们可以得到的是:
同理,我们可以得到:
然而,因为 题目保证没有上限的限制就有解,所以,(gcd(a_{x-1} , a_x)) 只存在一个质因子。
只存在一个质因子,又 (ecause a_i ot = a_{i-1} (1 < i < n)) ,( herefore p_i = gcd(a_{i-1},a_i) (1 < i < n)).
我们不需要算那么多个 (gcd),只需要算出 (p_2),就可以递推得到整个序列!
时间复杂度:(O(Tn log m)).(只保证 (70 \%) 的数据答案正确,不保证 (100 \%) 的数据答案都正确)
实际得分:(70pts).
算法四
对于 (100 \%) 的数据,(T leq 5),(n leq 10^5),(m leq 10^{18}).
可以发现,(O(Tn log m)) 完全可以通过本题,但是,对于 (a_i = a_{i+1}) 的情况,(gcd(a_{i-1} , a_i) = a_i),根本没有起到一点点降低时间的可能。
但是,我们只需要 求出一个 (p_i) 就可以得到整个序列,注意到题目保证:
至少存在一组 ((i,j)),使得 (a_i ot = a_j).
这说明整个序列 不完全一样,也就是说 至少存在一组 (a_i ot = a_{i+1}).
那么,我们只需要找到这个位置,求出 (p_i),然后往两边递推就可以得到答案。
时间复杂度:(O(Tn log m)).(保证答案正确)
实际得分:(100pts).