杜教筛及其时间复杂度分析

14 篇文章 0 订阅
3 篇文章 0 订阅

杜教筛

杜教筛用于求一类积性函数的前缀和,时间复杂度可以做到 O ( n 2 3 ) O(n^{\frac{2}{3}}) O(n32)

方法

设我们要求的是积性函数函数 f ( x ) f(x) f(x) 的前缀和 S ( n ) = ∑ i = 1 n f ( i ) S(n) = \sum_{i = 1}^n f(i) S(n)=i=1nf(i)
我们取一个积性函数 g g g g g g 具体是什么由 f f f 决定,但这不影响推式子)则 ∑ i = 1 n ( f ∗ g ) ( i ) = ∑ i = 1 n ∑ d ∣ i g ( d ) f ( i d ) = ∑ d = 1 n g ( d ) ∑ d ∣ i f ( i d ) = ∑ d = 1 n g ( d ) ∑ j = 1 ⌊ n d ⌋ f ( j ) = ∑ d = 1 n g ( d ) S ( ⌊ n d ⌋ ) \begin{aligned}\sum_{i = 1}^n (f*g)(i) = &\sum_{i = 1}^n\sum_{d | i} g(d)f\left(\frac{i}{d}\right) \\ = &\sum_{d = 1}^n g(d)\sum_{d | i}f\left(\frac{i}{d}\right) \\ =&\sum_{d = 1}^n g(d)\sum_{j = 1}^{\left\lfloor\frac{n}{d}\right\rfloor}f(j) \\ =&\sum_{d = 1}^n g(d) S\left(\left\lfloor\frac{n}{d}\right\rfloor\right)\end{aligned} i=1n(fg)(i)====i=1ndig(d)f(di)d=1ng(d)dif(di)d=1ng(d)j=1dnf(j)d=1ng(d)S(dn) 要求 S ( n ) S(n) S(n),所以尝试计算 g ( 1 ) S ( n ) = ∑ d = 1 n g ( d ) S ( ⌊ n d ⌋ ) − ∑ d = 2 n g ( d ) S ( ⌊ n d ⌋ ) = ∑ i = 1 n ( f ∗ g ) ( i ) − ∑ d = 2 n g ( d ) S ( ⌊ n d ⌋ ) \begin{aligned} g(1)S(n) = &\sum_{d = 1}^n g(d) S\left(\left\lfloor\frac{n}{d}\right\rfloor\right) - \sum_{d = 2}^n g(d) S\left(\left\lfloor\frac{n}{d}\right\rfloor\right) \\ =& \sum_{i = 1}^n (f*g)(i) - \sum_{d = 2}^n g(d) S\left(\left\lfloor\frac{n}{d}\right\rfloor\right) \end{aligned} g(1)S(n)==d=1ng(d)S(dn)d=2ng(d)S(dn)i=1n(fg)(i)d=2ng(d)S(dn) 也就是说如果 ( f ∗ g ) (f*g) (fg) g g g 的前缀和都能很快地算,后面那个数论分块,我们就可以得到 S ( n ) S(n) S(n) 了!

举例

莫比乌斯函数

f = μ f = \mu f=μ,注意到 μ ∗ 1 = ε \mu*1 = \varepsilon μ1=ε 1 ( x ) = 1 1(x) = 1 1(x)=1 ε ( x ) = [ x = 1 ] \varepsilon(x) = [x = 1] ε(x)=[x=1] 的前缀和都很显然,于是取 g = 1 g = 1 g=1 即可。

欧拉函数

f = φ f = \varphi f=φ,注意到 φ ∗ 1 = i \varphi * 1 = i φ1=i 1 ( x ) = 1 1(x) = 1 1(x)=1 i ( x ) = x i(x) = x i(x)=x 的前缀和都很显然,于是取 g = 1 g = 1 g=1 即可。

时间复杂度

只考虑 g g g f ∗ g f * g fg 的前缀和能够 O ( 1 ) O(1) O(1) 计算的情况。设 T ( n ) T(n) T(n) 为计算 S ( n ) S(n) S(n) 的时间复杂度(大 O O O 记号),有 T ( n ) = O ( n ) + ∑ i = 2 n ( T ( i ) + T ( n i ) ) = O ( n ) + ∑ i = 2 n ( O ( i ) + ∑ j = 2 i T ( j ) + O ( n i ) + ∑ j = 2 n i T ( j ) ) \begin{aligned}T(n) = &O\left(\sqrt n\right) + \sum_{i = 2}^{\sqrt n} \left(T(i) + T\left(\frac{n}{i}\right)\right) \\= &O\left(\sqrt n\right) + \sum_{i = 2}^{\sqrt n}\left(O\left(\sqrt i\right) + \sum_{j = 2}^{\sqrt i} T(j) +O\left(\sqrt{\frac{n}{i}}\right) + \sum_{j = 2}^{\sqrt {\frac{n}{i}}} T(j)\right)\end{aligned} T(n)==O(n )+i=2n (T(i)+T(in))O(n )+i=2n O(i )+j=2i T(j)+O(in )+j=2in T(j) 其中 O ( n ) O\left(\sqrt n\right) O(n ) 是该层合并复杂度。

通常用的大 O O O 记号是渐进时间复杂度,可以理解为 n → ∞ n\to \infty n 的时间消耗,也可以作为最坏时间复杂度理解,因此通常用的大 O O O 记号的定义是:假设程序进行常数运算的次数为 ϕ ( n ) \phi(n) ϕ(n),存在一个函数 τ ( n ) \tau(n) τ(n) 使得 lim ⁡ n → ∞ ϕ ( n ) τ ( n ) = C \lim\limits_{n\to \infty}\frac{\phi(n)}{\tau(n)} = C nlimτ(n)ϕ(n)=C,其中 C C C 是一个 非零 常数,那么该程序时间复杂度为 O ( τ ( n ) ) O(\tau(n)) O(τ(n))。在数学上称 ϕ ( n ) \phi(n) ϕ(n) τ ( n ) \tau(n) τ(n) 是同阶的。

因此从定义可以看出,大 O O O 记号是忽略了高阶无穷小的,只保留同阶无穷。

如果 lim ⁡ x → ∞ α ( x ) β ( x ) = 0 \lim\limits_{x \to \infty}\frac{\alpha(x)}{\beta(x)} = 0 xlimβ(x)α(x)=0,则称 β ( x ) \beta(x) β(x) α ( x ) \alpha(x) α(x) 低阶无穷小;
如果 lim ⁡ x → ∞ α ( x ) β ( x ) = C ≠ 0 \lim\limits_{x \to \infty}\frac{\alpha(x)}{\beta(x)} = C \neq 0 xlimβ(x)α(x)=C=0 C C C 是常数,则称 β ( x ) \beta(x) β(x) α ( x ) \alpha(x) α(x) 的同阶无穷小;
如果 lim ⁡ x → ∞ α ( x ) β ( x ) = ∞ \lim\limits_{x \to \infty}\frac{\alpha(x)}{\beta(x)} = \infty xlimβ(x)α(x)=,则称 β ( x ) \beta(x) β(x) α ( x ) \alpha(x) α(x) 高阶无穷小。

由于 lim ⁡ n → ∞ n 1 2 n 1 4 = lim ⁡ n → ∞ n 1 4 = ∞ \lim\limits_{n \to \infty}\frac{n^{\frac{1}{2}}}{n^{\frac{1}{4}}} = \lim\limits_{n \to \infty} n^\frac{1}{4} = \infty nlimn41n21=nlimn41=,所以 n \sqrt{\sqrt n} n 相对 n \sqrt n n 是高阶无穷小量,对于大 O O O 记号可以忽略,所以 T ( n ) = O ( n ) + ∑ i = 2 n ( O ( i ) + O ( n i ) ) \begin{aligned}T(n) = &O\left(\sqrt n\right) + \sum_{i = 2}^{\sqrt n}\left(O\left(\sqrt i\right) + O\left(\sqrt{\frac{n}{i}}\right) \right)\end{aligned} T(n)=O(n )+i=2n (O(i )+O(in )) (粗略估计)由均值不等式 i + n i ≥ 2 i n i = 2 n 1 4 \sqrt i + \sqrt{\frac{n}{i}} \geq 2\sqrt{\sqrt{i\frac{n}{i}}} = 2n^{\frac{1}{4}} i +in 2iin =2n41,于是 ∑ i = 2 n ( O ( i ) + O ( n i ) ) ≥ n 1 2 n 1 4 = n 3 4 \sum\limits_{i = 2}^{\sqrt n}\left(O\left(\sqrt i\right) + O\left(\sqrt{\frac{n}{i}}\right) \right) \geq n^{\frac{1}{2}} n^{\frac{1}{4}} = n^{\frac{3}{4}} i=2n (O(i )+O(in ))n21n41=n43,于是 T ( n ) = O ( n 3 4 ) T(n) = O\left(n^{\frac{3}{4}}\right) T(n)=O(n43)

但是我们可以先线性筛预处理出一部分前缀和,这样某些前缀和就能之间查询了。假设我们预处理了前 m m m 个前缀和,那么复杂度变为 T ( n ) = O ( m ) + O ( n ) + ∑ i = 2 n ( [ i > m ] O ( i ) + [ n i > m ] O ( n i ) ) \begin{aligned} T(n) =&O(m) + O\left(\sqrt n\right) + \sum_{i = 2}^{\sqrt n}\left(\left[\sqrt i > m\right]O\left(\sqrt i\right) + \left[\sqrt{\frac{n}{i}} > m\right]O\left(\sqrt{\frac{n}{i}}\right) \right)\end{aligned} T(n)=O(m)+O(n )+i=2n ([i >m]O(i )+[in >m]O(in )) m ≥ n 1 4 m \geq n^{\frac{1}{4}} mn41(在一定限度内 m m m 肯定越大越好),那么 T ( n ) = O ( m ) + O ( n ) + ∑ i = 2 n [ n i > m ] O ( n i ) = O ( m ) + O ( n ) + ∑ i = 2 n m 2 O ( n i ) ≥ O ( m ) + O ( n ) + O ( n n m 2 ) \begin{aligned} T(n) =&O(m) + O\left(\sqrt n\right) + \sum_{i = 2}^{\sqrt n}\left[\sqrt{\frac{n}{i}} > m\right]O\left(\sqrt{\frac{n}{i}}\right) \\ =&O(m) + O\left(\sqrt n \right) + \sum_{i = 2}^{\frac{n}{m^2}} O\left(\sqrt{\frac{n}{i}}\right)\\ \geq &O(m) + O\left(\sqrt n\right) + O\left(\frac{n\sqrt n}{m^2}\right)\end{aligned} T(n)==O(m)+O(n )+i=2n [in >m]O(in )O(m)+O(n )+i=2m2nO(in )O(m)+O(n )+O(m2nn ) m = n 2 3 m = n^{\frac{2}{3}} m=n32 时能取到最优复杂度 O ( n 2 3 ) O(n^{\frac{2}{3}}) O(n32)

因此杜教筛的时间复杂度为 O ( n 2 3 ) O(n^\frac{2}{3}) O(n32)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值