P6523 「Wdoi-1」加密通信 题解
简要题意:
给定一个数列 \(a_1 , a_2 \cdots a_{n-1}\),求 任意一个满足以下条件的长度为 \(n\) 的质数数列 \(\text{ans}\):
本题是某洛谷公开赛 \(T1\),有一定思维难度。
前记
本人 \(193ms\) 的代码截止 \(\text{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 \times 10^4\) 个。
你在这 \(8 \times 10^4\) 个中枚举因数,然后 \(O(n)\) 验证。
时间复杂度:\(O(Tn \times 8 \times 10^4)\).
简单估计:\(O(5 \times 10^5 \times 8 \times 10^4 = 40 \times 10^9 = 4 \times 10^{10})\).
所以理论上,如果跑满时间复杂度是根本无法通过的,也无法分析该程序具体的常数是多少。
可能出题人的数据有点弱,导致每次 \(O(n)\) 根本跑不满,枚举到半路就被剪枝了吧。
所以按照算法一的思路,卡一卡常数就可以得到 \(40pts\).
时间复杂度:\(O(Tn \sqrt{m})\).
实际得分:\(20pts\) ~ \(40pts\).
算法三
对于 \(70 \%\) 的数据,\(a_i \not = a_{i+1}\).
暂时我们想不出,\(a_i \not = a_{i+1}\) 有什么性质。
那么先把得到的 \(n-1\) 个方程组列出来吧:
只看前两个方程,我们可以得到的是:
同理,我们可以得到:
然而,因为 题目保证没有上限的限制就有解,所以,\(\gcd(a_{x-1} , a_x)\) 只存在一个质因子。
只存在一个质因子,又 \(\because a_i \not = a_{i-1} (1 < i < n)\) ,\(\therefore 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 \not = a_j\).
这说明整个序列 不完全一样,也就是说 至少存在一组 \(a_i \not = a_{i+1}\).
那么,我们只需要找到这个位置,求出 \(p_i\),然后往两边递推就可以得到答案。
时间复杂度:\(O(Tn \log m)\).(保证答案正确)
实际得分:\(100pts\).