Min_25 筛的另一种实现

众所周知,\(\text{Min25}\) 筛的复杂度是假的。

众所周知,虽然洲阁筛的复杂度是真的,但是跑的没 \(\text{Min25}\) 筛快,而且非常难写。

众所周知,\(\text{Min25}\) 筛的复杂度假在了第二部分。

于是我们期望能对第二部分改进,以获得一个复杂度正确,而且比洲阁筛好写一点的筛子。


一些定义:

  • \(P\):质数集,\(p_k\) 为第 \(k\) 个质数,特别的,规定 \(p_0=1\)
  • \(\operatorname{minp}(n)\)\(n\) 的最小质因子在质数集中的排名
  • \(\operatorname{maxp}(n)\)\(\leq \sqrt{n}\) 的最大质数在质数集中的排名
  • \(f(i)\):我们要求前缀和的函数
  • \(N\):最后要求的 \(\sum_{i=1}^{N}f(i)\),与过程中的 \(n\) 区分
  • \(n\):过程中的 \(n\),即 \(n\in\{\lfloor\dfrac{N}{1}\rfloor,\lfloor\dfrac{N}{2}\rfloor,\lfloor\dfrac{N}{3}\rfloor,\ldots,\lfloor\dfrac{N}{N}\rfloor\}\),这样的 \(n\) 一共有 \(\sqrt{N}\) 个。
  • \(F(n)\)\(f(i)\) 的前缀和,即 \(F(n)=\sum_{i=1}^{n}f(i)\)
  • \(F_p(n)\)\(f(i)\) 在质数处的前缀和,即 \(F_p(n)=\sum_{i=1}^{n}[i\in P]f(i)\)

\(\text{Min25}\) 筛的主要思想是将质数处和合数处的值分开来计算,即:

\[F(N)=f(1)+F_p(N)+\sum_{j=2}^{N}[j\notin P]f(j) \]

我们称 \(F_p(N)\) 为第一部分,\(\sum_{j=2}^{N}[j\notin P]f(j)\) 为第二部分。


第一部分是相同的,简单复述一下:

首先构造完全积性函数 \(f'(p)=f(p)\)。设 \(g(i,n)=\sum_{j=2}^{n}[j\in P\vee \operatorname{minp}(j)>i]f'(p)\),那么我们就有 \(F_p(n)=g(\operatorname{maxp}(n),n)\)

考虑递推 \(g(i,n)\),有初值 \(g(0,n)=\sum_{j=2}^{n}f'(j)\),递推式考虑减去最小质因子为 \(i\) 的贡献,由于是完全积性函数,我们无需枚举质因子的指数:

\[g(i,n)=g(i-1,n)-f'(p_i)\bigg(g(i-1,\lfloor\dfrac{n}{p_i}\rfloor)-g(i-1,p_{i-1})\bigg) \]

由于对于 \(p_i>\sqrt{n}\) 的没有需要减去的贡献,因此对于每个 \(n\) 只会有 \(\operatorname{maxp}(n)\) 次的转移,所以复杂度为:

\[\sum_{i=1}^{\sqrt{N}}O(\dfrac{\sqrt{i}}{\log \sqrt{i}})+\sum_{i=1}^{\sqrt{N}}O(\dfrac{\sqrt{\frac{N}{i}}}{\log \sqrt{\frac{N}{i}}})\approx O(\dfrac{N^{\frac{3}{4}}}{\log N}) \]


重点分析第二部分。

朴素的 \(\text{Min25}\) 筛在这一部分设的是 \(h(i,n)=\sum_{j=2}^{n}[\operatorname{minp}(j)>i]f(j)\),边界为 \(p_i\geq n\)\(h(i,n)=0\),转移为:

\[h(i,n)=F_p(n)-F_p(p_i)+\sum_{j>i}\sum_{e\geq 1,p_j^e\leq n}f(p_j^e)\bigg(h(j,\lfloor\dfrac{n}{p_j^e}\rfloor)+[e\ne 1]\bigg) \]

这个递推式的复杂度实际上是 \(O(n^{1-\epsilon})\) 的,因此 \(\text{Min25}\) 实际上并不是亚指数筛。

考虑复杂度在哪里出现了退化:我们枚举了 \(p_j\)

这很不好。

我们尝试用和 \(g(i,n)\) 一样的思路,每次在 \(h(i+1,n)\) 的基础上加上由 \(p_{i+1}\) 产生的贡献,这样我们可以写出递推式:

\[h(i,n)=h(i+1,n)+\sum_{e\geq 1,p_{i+1}^e\leq n}f(p_{i+1}^e)\bigg(h(i+1,\lfloor\dfrac{n}{p_{i+1}^e}\rfloor)\bigg) \]

还可以更优美一些:

\[h(i,n)=\sum_{e\geq 0,p_{i+1}^e\leq n}f(p_{i+1}^e)\bigg(h(i+1,\lfloor\dfrac{n}{p_{i+1}^e}\rfloor)\bigg) \]

这是什么?为什么式子这么熟悉?

这是洲阁筛的第二部分。

在这里精细实现可以做到 \(O(\dfrac{N^{\frac{3}{4}}}{\log N})\),但是我们期望得到一个更好写的做法。


洲阁筛复杂在哪里?需要写一个后缀和。

为什么会有这个后缀和的贡献而不能像 \(g\) 一样没有贡献?因为存在 \(p_{i+1}>\sqrt{n},e=1\) 时从 \(f(p_{i+1})h(i+1,1)\) 的转移,也就是 \(>\sqrt{n}\) 的质数的贡献。

如何去掉这个转移?在状态中去掉关于质数的贡献。


我们设 \(h(i,n)=\sum_{j=2}^{n}[j\notin P\land \operatorname{minp}(j)>i]f(j)\),此时对于 \(i>\sqrt{n}\) 就有 \(g(i,n)=0\),这样的话状态数就缩减到了 \(O(\dfrac{N^{\frac{3}{4}}}{\log N})\)

考虑转移:

\[h(i,n)=h(i+1,n)+\sum_{e\geq 1,p_{i+1}^e\leq n}^{}f(p_{i+1}^e)\bigg([e\ne 1]+h(i+1,\lfloor\dfrac{n}{p_{i+1}^e}\rfloor)+F_p(\lfloor\dfrac{n}{p_{i+1}^e}\rfloor)-F_p(p_i)\bigg) \]

虽然式子看上去变得更复杂了,但是因为状态数降下来,所以转移可以暴力实现,实现难度和 \(\text{Min25}\) 筛的难度差不多。

由于转移看上去不能确定是 \(O(1)\) 的,因此至此还不能确定总时间复杂度。

考虑对于一个 \(n\) 的总转移次数 \(t(n)\),我们枚举 \(e\),求出能转移到 \(n\) 的整数的数量(先不考虑只从质数处转移,最后乘上一个质数密度即可):

\[t(n)=\sum_{e=2}^{\log n}O(n^{\frac{1}{e}})<\sum_{e=0}^{\log n}O(\dfrac{\sqrt{n}}{2^e})<2\times O(\sqrt{n}) \]

(这里的第一个 \(<\) 是渐进意义上的)

因此第二部分总复杂度为:

\[\sum_{i=1}^{\sqrt{N}}O(\dfrac{\sqrt{i}+t(i)}{\log \sqrt{i}})+\sum_{i=1}^{\sqrt{N}}O(\dfrac{\sqrt{\frac{N}{i}}+t(\frac{N}{i})}{\log \sqrt{\frac{N}{i}}})\approx O(\dfrac{N^{\frac{3}{4}}}{\log N}) \]

完结撒花~


PS:关于实际效率

参考在 \(\text{Min25}\) 筛模板题的提交:

假复杂度做法\(O(N^{1-\epsilon})\),1.75 s)

正确复杂度做法\(O(\dfrac{N^{\frac{3}{4}}}{\log N})\),3.27 s)

PN 筛\(O(N^{\frac{2}{3}})\),4.56 s)

从上往下渐进复杂度在变优,实际速度在变慢

posted @ 2023-02-17 15:43  Legitimity  阅读(59)  评论(0编辑  收藏  举报