洲阁筛

前置知识

定义

洲阁筛是一种能在亚线性时间复杂度内求出大多数积性函数前缀和的筛法.

下面将以求解 ∑i=1nf(i)\displaystyle\sum_{i=1}^nf(i) 为例,具体阐述洲阁筛的原理.

约定

  • P\mathbb P 表示质数集,pip_i 表示第 ii 个质数.
  • mm 表示 n\sqrt n 内的质数个数.

要求

当 p∈P,c∈Np\in\mathbb P,c\in\mathbb N 时,f(pc)f(p^c) 为一个关于 pp 的低阶多项式.

思想

  • 对于任意 [1,n][1,n] 内的整数,其至多只有一个 >n>\sqrt n 的质因子.
  • 利用 ⌊ni⌋(i∈[1,n]∩N)\left\lfloor\dfrac ni\right\rfloor(i\in[1,n]\cap\mathbb N) 只有 n\sqrt n 级别个取值的性质来降低时间复杂度.

过程

将 [1,n][1,n] 内的所有整数按是否有 >n>\sqrt n 的质因子分为两类:

∑i=1nf(i)=∑i=1n[∃d∈(n,n]∩P,d∣i]f(i)+∑i=1n[∀d∈(n,n]∩P,d∤i]f(i)\sum_{i=1}^nf(i)=\sum_{i=1}^n\left[\exists d\in(\sqrt n,n]\cap\mathbb P,d\mid i\right]f(i)+\sum_{i=1}^n\left[\forall d\in(\sqrt n,n]\cap\mathbb P,d\nmid i\right]f(i)

对于前半部分,枚举最大因子,根据积性函数的性质可以转换:

∑i=1nf(i)=∑i=1nf(i)⋅(∑d=⌊n⌋+1⌊ni⌋[d∈P]f(d))+∑i=1n[∀d∈(n,n]∩P,d∤i]f(i)\sum_{i=1}^nf(i)=\sum_{i=1}^{\sqrt n}f(i)\cdot\left(\sum_{d=\lfloor\sqrt n\rfloor+1}^{\lfloor\frac ni\rfloor}[d\in\mathbb P]f(d)\right)+\sum_{i=1}^n\left[\forall d\in(\sqrt n,n]\cap\mathbb P,d\nmid i\right]f(i)

前后部分可以分别计算.

Part 1

计算 ∑i=1nf(i)⋅(∑d=⌊n⌋+1⌊ni⌋[d∈P]f(d))\displaystyle\sum_{i=1}^{\sqrt n}f(i)\cdot\left(\sum_{d=\lfloor\sqrt n\rfloor+1}^{\lfloor\frac ni\rfloor}[d\in\mathbb P]f(d)\right).

考虑枚举 ii,然后 O(1)O(1) 计算括号内部分.

记 g(t,l)=∑i=1l[∀j∈[1,t],gcd⁡(i,pj)=1]f(i)\displaystyle g(t,l)=\sum_{i=1}^l[\forall j\in[1,t],\gcd(i,p_j)=1]f(i),即 [1,l][1,l] 中与 p1,p2,…,ptp_1,p_2,\dots,p_t 均互质的数的 ff 值之和.

这样 Part 1 的计算就变成了 ∑i=1nf(i)⋅g(m,⌊ni⌋)\displaystyle\sum_{i=1}^{\sqrt n}f(i)\cdot g\left(m,\left\lfloor\frac ni\right\rfloor\right).

边界 g(0,l)=∑i=1lf(i)g(0,l)=\sum_{i=1}^lf(i),转移 g(t,l)=g(t−1,l)−f(pt)⋅g(t−1,⌊lpt⌋)g(t,l)=g(t-1,l)-f(p_t)\cdot g\left(t-1,\left\lfloor\frac l{p_t}\right\rfloor\right).

ll 共有 n\sqrt n 级别种取值,对于每种取值则需要枚举其质因子,所以复杂度为 O(nln⁡n⋅n)=O(nlog⁡n)\displaystyle O\left(\frac{\sqrt n}{\ln\sqrt n}\cdot\sqrt n\right)= O\left(\frac n{\log n}\right),需要优化.

注意到 pt+12>lp_{t+1}^2>l 时符合条件的数只有 11,所以此时 g(t,l)=f(1)=1g(t,l)=f(1)=1.

代入递推式可得:当 pt2>lp_t^2>l 时,g(t,l)=g(t−1,l)−f(pt)g(t,l)=g(t-1,l)-f(p_t).

所以一旦发现 pt2>lp_t^2>l 就停止转移,记此时的 tt 为 tlt_l,则 ∀t>tl,g(t,l)=g(tl,l)−∑i=tlt−1f(pi)\forall t>t_l,g(t,l)=g(t_l,l)-\sum_{i=t_l}^{t-1}f(p_i).

预处理质数的 ff 值前缀和即可快速求出 gg,时间复杂度被优化至 O(n34log⁡n)O\left(\dfrac{n^{\frac34}}{\log n}\right).

Part 2

计算 ∑i=1n[∀d∈(n,n]∩P,d∤i]f(i)\displaystyle\sum_{i=1}^n\left[\forall d\in(\sqrt n,n]\cap\mathbb P,d\nmid i\right]f(i).

记 h(t,l)=∑i=1l[i=∏j=tmpjcj,cj∈N]f(i)\displaystyle h(t,l)=\sum_{i=1}^l\left[i=\prod_{j=t}^mp_j^{c_j},c_j\in\mathbb N\right]f(i),即 [1,l][1,l] 中所有只含 pt,pt+1,…,pmp_t,p_{t+1},\dots,p_m 质因子的数的 ff 值之和.

Part 2 即为求 h(0,n)h(0,n).

边界 h(m+1,l)=1h(m+1,l)=1,转移 h(t,l)=h(t+1,l)+∑c∈N∗f(ptc)⋅h(t+1,⌊lptc⌋)\displaystyle h(t,l)=h(t+1,l)+\sum_{c\in\mathbb N^*}f(p_t^c)\cdot h\left(t+1,\left\lfloor\frac l{p_t^c}\right\rfloor\right).

ll 共有 n\sqrt n 级别种取值,所以直接转移复杂度为 O(n⋅nln⁡n)=O(nlog⁡n)\displaystyle O\left(\sqrt n\cdot\frac{\sqrt n}{\ln\sqrt n}\right)= O\left(\frac n{\log n}\right),需要优化.

与 gg 的优化方式类似,注意到 pt>lp_t>l 时,能用 pt,pt+1,…,pmp_t,p_{t+1},\dots,p_m 组成的数只有 11,此时的 h(t,l)=f(1)=1h(t,l)=f(1)=1.

类似的,推出 ∀pt2>l,h(t,l)=h(t+1,l)+f(pt)\forall p_t^2>l,h(t,l)=h(t+1,l)+f(p_t).

所以一旦发现 pt2>lp_t^2>l 就停止转移,记此时的 tt 为 tlt_l,之后用到 hh 时,把此时的 hh 值加上 ∑i=ptlmin⁡(l,n)[i∈P]f(i)\displaystyle\sum_{i=p_{t_l}}^{\min(l,\sqrt n)}[i\in\mathbb P]f(i) 即可.

时间复杂度被优化至 O(n34log⁡n)O\left(\dfrac{n^{\frac34}}{\log n}\right).

求和

算出了 Part 1 和 Part 2 的答案,将其相加即为 ∑i=1nf(i)\displaystyle\sum_{i=1}^nf(i).

参考

积性函数线性筛/杜教筛/洲阁筛学习笔记 | Bill Yang's Blog

本文内容来自 OI Wiki《洲阁筛》;作者与修订历史见原文。AIOJ 对排版、站内链接和资源路径做了格式适配。

内容依 CC BY-SA 4.0 与 SATA 许可共享;附加条款以原文声明为准。感谢 OI Wiki 作者与贡献者;请按 SATA 约定前往 OI Wiki 仓库 Star 支持。