题解:P4359&P8316 [CQOI2016] 伪光滑数(加强版)

原题 加强版

考虑设 \(p_i\) 表示从小到大第 \(i\) 个质数,设 \(f_{i,j}\) 表示有 \(i\) 个不去重质因数,最大质因数为 \(p_j\) 的合法的数的集合。其中 \(p_i\le397\),所以最多只有 \(78\) 个质数。

发现 \(f\) 可以这样转移:

\[f_{i,j}=\{p_jx|x\in\bigcup_{k=1}^{j}f_{i-1,k}\} \]

考虑同时转移 \(\bigcup_{k=1}^{j}f_{i-1,k}\),设 \(g_{i,j}=\bigcup_{k=1}^{j}f_{i,k}\),则有:

\[f_{i,j}=\{p_jx|x\in g_{i-1,j}\} \]

\[g_{i,j}=g_{i,j-1}\cup f_{i,j} \]

由于 \(p_j^i>n\)\(f_{i,j}=\varnothing\),事实上合法的数不会太多,我们可以用可持久化左偏树维护 \(f\)\(g\)。先枚举 \(i\),再枚举 \(p_j^i\le n\)\(j\),更新 \(f\)\(g\)。最终答案的集合 \(A=\bigcup f\),用优先队列 BFS \(A\) 的左偏树,分 \(k\) 次取出队头,并将其在左偏树上的儿子加入优先队列即可。总时间复杂度为 \(O(78\log n^2+k\log n)\)

注意原题有 \(n<128\) 的点,判断 \(p_j^i\) 是否大于 \(n\) 要开 int128,且要注意需要把 \(f_{1,j}\) 并到 \(A\) 上。

posted @ 2025-02-25 15:58  FugiPig  阅读(23)  评论(0)    收藏  举报