题解:CF2041F Segmentation Folds

· · 题解

F. Segmentation Folds

给定 [l,r],你需要选择以下操作任一执行:

如果这个区间 [l,r] 无法操作,则称这个区间为一个结束状态。否则继续递归。

问所有结束状态中,长度最小的有多少个。答案对 998244353 取模。

多测,1\leq t\leq 10

--- 为了规避浮点问题,我们把所有区间的 $l,r$ 都乘上 $2$。 我们首先要把 $[2l,2r]$ 之间的素数都筛出来。我们先预处理到 $\sqrt{2r}$ 的所有质数,然后把这些质数在 $[2l,2r]$ 内的倍数筛出来。具体参见 [P1835 素数密度](https://www.luogu.com.cn/problem/P1835)。 然后大力搜索即可。 搜索的时候可以通过二分找到第一个和最后一个合法的 $x$。但是这样复杂度多带一个 $\log$。我们把二分的内容拎出去,在预处理完质数之后,枚举所有的情况找到上一个下一个质数。 搜索的结束状态一定是两个相邻的质数。只有 $\mathcal O(\frac{n}{\log n})$ 个。而每个状态只有 $\mathcal O(\log n)$ 个前驱状态,所以直接搜索甚至不带记忆化的复杂度是 $\mathcal O(n)$ 的。 总复杂度瓶颈在筛质数的 $\mathcal O(n\log \log n)$。 代码写的有点丑了,丑在了: >我们把二分的内容拎出去,在预处理完质数之后,枚举所有的情况找到上一个下一个质数。 这一部分。写的是二分,如果写双指针最后复杂度就是 $\mathcal O(n\log \log n)$。这份代码是 $\mathcal O(n\log n)$ 的。 <https://codeforces.com/contest/2041/submission/294604119>