CF1468L - Prime Divisors Selection
CF1468L - Prime Divisors Selection
题目大意
对于一个序列 \(A\) ,一个合法的质因子序列 \(P\) 满足 \(\forall P_i|A_i,P_i\ is\ a\ prime\)
给定一个序列 \(a_i,i\in[1,n]\) ,求选出 \(k\) 个数,使得对于选出的序列 \(A\)
不存在一个 \(P\) 使得 \(P\) 中某个元素恰好出现一次
\(n\leq 1000,a_i\leq 10^{18}\)
分析
由题目的意思我们知道肯定要分解质因数
Pollard's_Rho!!!
\(10^{18}\) 分解质因数可不是开玩笑的。。。
所以先考虑合法 \(A\) 的判定
判定 \(A\) 合法
假设可以存在一个元素恰好出现一次 \(x\) ,那么在 \(A\) 所有元素质因子中至少要包含一个 \(x\)
并且,不存在两个元素只包含 \(x\)
也就是说,对于合法的 \(A\) 中出现的所有质因子 \(x\) ,都必须存在两个元素只包含 \(x\)
我们称只包含 \(x\) 作为质因子的元素为 \(x\) -元素,为了构造合法的 \(A\) ,我们必须对于一些 \(x\) 选出若干对 \(x\) -元素
对于每个 \(x\) ,我们只把前两个 \(x-\) 元素视为有效,假设有 \(c\) 对这样的元素
那么情况分几种
\(2|k,2c\ge k\) ,那么直接随意选完即合法
\(2c\ge k,2\not |k\) ,此时我们需要选出部分对,使得剩下的元素中存在一个数它的因子集已经被选
枚举剩下一个元素,判定合法即可
- \(2c\leq k\) ,此时可以将 \(c\) 对全部选出,判断是否还存在 \(k-2c\) 个可以选择即可
质因数分解
亲身试验,我的Pollards_Rho它T飞了
容易发现,对于 \(x-\) 元素我们只需要找到它的 \(a_i=x^k\)
对于其他元素我们只需要找到 \(a_i\) 对应的 \(x\) 的集合,或者判断无法被 \(x-\) 元素集合包含
由于 \(n\leq 1000\) ,我们可以先得到 \(x-\) 元素集合,其他元素我们最后一个个判定
找到 \(a_i=x^k\) 问题简化了很多
如果你相信std::pow,可以直接来
只需要找到一个最小的 \(k'\) ,使得 \(a_i=x'^{k'}\) ,判定 \(x'\) 是否为质数,如果是则停止,否则继续分解 \(x'\)
对于 \(k'\leq 3\) ,甚至更大一些的情况,std::pow比较可信
而 \(k'>3\) 的情况(实际上 \(k'=4\) 被 \(k'=2\) 包含,所以是 \(k'\ge 5\) )
实际上 \(x'\) 已经很小了,直接枚举质数即可
素数判定依然需要 \(\text{Miller_Rabin}\)
,但是至少不用Pollards_Rho了
1 | const int N=1e5+10; |