跳转至

洲阁筛

前置知识

定义

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

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

约定

  • P 表示质数集,pi 表示第 i 个质数.
  • m 表示 n 内的质数个数.

要求

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

思想

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

过程

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

∑i=1nf(i)=∑i=1n[∃d∈(n,n]∩P,d∣i]f(i)+∑i=1n[∀d∈(n,n]∩P,d∤i]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)

前后部分可以分别计算.

Part 1

计算 ∑i=1nf(i)⋅(∑d=⌊n⌋+1⌊ni⌋[d∈P]f(d)).

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

记 g(t,l)=∑i=1l[∀j∈[1,t],gcd(i,pj)=1]f(i),即 [1,l] 中与 p1,p2,…,pt 均互质的数的 f 值之和.

这样 Part 1 的计算就变成了 ∑i=1nf(i)⋅g(m,⌊ni⌋).

边界 g(0,l)=∑i=1lf(i),转移 g(t,l)=g(t−1,l)−f(pt)⋅g(t−1,⌊lpt⌋).

l 共有 n 级别种取值,对于每种取值则需要枚举其质因子,所以复杂度为 O(nln⁡n⋅n)=O(nlog⁡n),需要优化.

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

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

所以一旦发现 pt2>l 就停止转移,记此时的 t 为 tl,则 ∀t>tl,g(t,l)=g(tl,l)−∑i=tlt−1f(pi).

预处理质数的 f 值前缀和即可快速求出 g,时间复杂度被优化至 O(n34log⁡n).

Part 2

计算 ∑i=1n[∀d∈(n,n]∩P,d∤i]f(i).

记 h(t,l)=∑i=1l[i=∏j=tmpjcj,cj∈N]f(i),即 [1,l] 中所有只含 pt,pt+1,…,pm 质因子的数的 f 值之和.

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

边界 h(m+1,l)=1,转移 h(t,l)=h(t+1,l)+∑c∈N∗f(ptc)⋅h(t+1,⌊lptc⌋).

l 共有 n 级别种取值,所以直接转移复杂度为 O(n⋅nln⁡n)=O(nlog⁡n),需要优化.

与 g 的优化方式类似,注意到 pt>l 时,能用 pt,pt+1,…,pm 组成的数只有 1,此时的 h(t,l)=f(1)=1.

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

所以一旦发现 pt2>l 就停止转移,记此时的 t 为 tl,之后用到 h 时,把此时的 h 值加上 ∑i=ptlmin(l,n)[i∈P]f(i) 即可.

时间复杂度被优化至 O(n34log⁡n).

求和

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

参考

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