专栏文章

铃悬的数学小讲堂——杜教筛

算法·理论参与者 45已保存评论 45

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
45 条
当前快照
1 份
快照标识符
@mhz5tpg6
此快照首次捕获于
2025/11/15 01:56
4 个月前
此快照最后确认于
2025/11/29 05:25
3 个月前
查看原文
# 铃悬的数学小讲堂——杜教筛
本篇算是【狄利克雷卷积及莫比乌斯反演】篇的后续 qwq。
本篇在读者掌握莫比乌斯反演与狄利克雷卷积的前提下,讲述了杜教筛算法,并伴有若干例题;另外还解释了如何利用贝尔级数更方便的使用杜教筛(要求具有一定生成函数知识)。
如果掌握莫比乌斯反演,也建议看一遍上篇博客;因为可能某些符号不太一样。

-2.符号及规定

同上篇。为方便此处再次写出:
  1. [P][P] 是指,当 PP 为真时,式子的值是 11 ;当 PP 为假时,式子的值是 00 。// 可以理解成, P 是一个 0/1 布尔值, [P][P] 就是 (int)P
  2. aba\mid b 是指 bbaa 整除,即存在一个整数 kk 使得 b=kab=kanmn\perp m 是指 nnmm 互质(注意,111\perp1 是成立的)。
  3. 数论函数(见下)用小写粗体字母或普通希腊文字母(如 f,g,h,μ,ϵ{\bf f,g,h},\mu,\epsilon )表示。// QAQ希腊文字母不能粗体

-1.前备知识

至少要理解莫比乌斯反演篇中的知识(即使不知道证明)qwq。

0.数论分块

对于一个像 F(n)=i=1nf(i)niF(n)=\sum_{i=1}^n f(i)\lfloor\frac ni\rfloor 这样的式子,如果我们可以 O(1)O(1) 求出 f(i)f(i) 的区间和,那么则可以在 O(n)O(\sqrt n) 的复杂度内计算 F(n)F(n) 。这依赖于以下引理:

引理 0.1

不同的 ni\lfloor\frac ni\rfloor 只有 O(n)O(\sqrt n) 种。
证明实际上很简单:如果 ini\geq\sqrt n,那么 1nin1\leq\lfloor\frac ni\rfloor\leq\sqrt n ,又只取整数值,自然只有 O(n)O(\sqrt n) 种取值。否则 i<ni<\sqrt n,但这样的 ii 只有 n\sqrt n 种,自然也只会有 O(n)O(\sqrt n) 种取值。
至于如何找出每一种取值,以及确定每个值对应的 ii 的区间,可以参考以下代码:
CPP
int ans = 0;
for (int i = 1, j; i <= n; i = j + 1) {
  j = n / (n / i);
  // j 为最大的满足 floor(n/t)=floor(n/i) 的 t
  ans += (n / i) * S(i, j);
}
代码中 S(a,b)S(a,b)i=anf(i)\sum_{i=a}^n f(i)。这段代码即可求出 i=1nf(i)ni\sum_{i=1}^n f(i)\lfloor\frac ni\rfloor
至于代码中的注释,则是因为 ntni    ntni    tnni    tnni\left\lfloor\frac nt\right\rfloor\geq\left\lfloor\frac ni\right\rfloor\iff \frac nt\geq\left\lfloor\frac ni\right\rfloor\iff t\leq\frac n{\left\lfloor\frac ni\right\rfloor}\iff t\leq\left\lfloor\frac n{\left\lfloor\frac ni\right\rfloor}\right\rfloor 所以 t 的最大值就是 n/(n/i)
如果求和上界是 mm 而不是 nnmnm\leq n),那就吧循环条件写成 imi\leq m 并令 j=min(m,n/(n/i)) 即可。i=1nf(i)g(ni)\sum_{i=1}^n f(i)g(\lfloor\frac ni\rfloor) 也可以用相同求法求。
同样的,如果求 i=1min(n,m)f(i)nimi\sum_{i=1}^{\min(n,m)}f(i)\lfloor\frac ni\rfloor\lfloor\frac mi\rfloor,也只需要令 j=min(n/(n/i),m/(m/i)),复杂度仍旧是 O(max(n,m))O(\sqrt{\max(n,m)})

1.杜教筛

如果给定函数 f,g\bf f,g,令 S(n)=i=1nf(i){\bf S}(n)=\sum_{i=1}^n{\bf f}(i),则有 i=1n(fg)(i)=i=1nxy=if(x)g(y)=y=1ng(y)xynf(x)=y=1ng(y)S(ny)\sum_{i=1}^n({\bf f*g})(i)=\sum_{i=1}^n\sum_{xy=i}{\bf f}(x){\bf g}(y)=\sum_{y=1}^n{\bf g}(y)\sum_{xy\leq n}{\bf f}(x)=\sum_{y=1}^n{\bf g}(y){\bf S}\left(\left\lfloor\frac ny\right\rfloor\right) 换句话说, g(1)S(n)=i=1n(fg)(i)y=2ng(y)S(ny){\bf g}(1){\bf S}(n)=\sum_{i=1}^n({\bf f*g})(i)-\sum_{y=2}^n{\bf g}(y){\bf S}\left(\left\lfloor\frac ny\right\rfloor\right) 这是由上面的等式右侧除了 y=1y=1 一项之外都移项到左边得到的。
由此我们可以得到一个 S{\bf S} 的计算方法(假设 (fg)(i)({\bf f*g})(i) 的前缀和与 g(i){\bf g}(i) 的区间和都可以 O(1)O(1) 计算,以下计算复杂度时亦作此假设):
CPP
int S(int n) {
  int ans = ???; // \sum_{i=1}^n(f*g)(i)
  for (int i = 2, j; i <= n; i = j + 1) {
    j = n / (n / i);
    ans -= Sg(i, j) * S(n / i);
  }
  ans /= g1;
  return ans;
}
其中 ans 初值为 i=1n(fg)(i)\sum_{i=1}^n({\bf f*g})(i)Sg(i,j)=k=ijg(k){\bf Sg}(i,j)=\sum_{k=i}^j{\bf g}(k)
这段代码如何优化复杂度呢?首先估计计算 S(N){\bf S}(N) 的过程中产生了多少递归计算。
以下,我们以 NN 指最初给出的 nn,以 nn 指递归调用产生的 nn

引理1.1

对于任意正整数 x,y,zx,y,z,有 zxy=zxy\left\lfloor\frac{\left\lfloor\frac zx\right\rfloor}y\right\rfloor=\left\lfloor\frac z{xy}\right\rfloor
证明也很简单:假设 z=ax+b,a=cy+dz=ax+b,a=cy+d,其中 0b<x,0d<y0\leq b<x,0\leq d<y,那么显然 zx=a,ay=c\left\lfloor\frac zx\right\rfloor=a,\left\lfloor\frac ay\right\rfloor=c,于是等号左边就等于 cc。同样的,我们有 z=cxy+(dx+b)z=cxy+(dx+b),其中 0dx+b(y1)x+(x1)=xy1<xy0\leq dx+b\leq(y-1)x+(x-1)=xy-1<xy,所以 zxy=c\left\lfloor\frac z{xy}\right\rfloor=c。所以等号左右相等。
由此可以发现,上面的代码在计算 S(N){\bf S}(N) 时,产生的(直接的或间接的)递归计算中的 nn 都是某个 Nx\left\lfloor\frac Nx\right\rfloor(因为如果这次的 nnnx\lfloor\frac nx\rfloor,下次一定是某个 nxi=nxi\left\lfloor\frac{\lfloor\frac nx\rfloor}i\right\rfloor=\lfloor\frac n{xi}\rfloor),从而根据引理 0.1 只有 O(N)O(\sqrt N) 次递归调用(如果 nn 相等的只计算一次的话),记忆化即可。
如果略去递归调用的复杂度,显然计算一次 S(n){\bf S}(n)O(n)O(\sqrt n)。根据引理 0.1 的证明过程可知递归调用的 nn 分别为 1,2,,N,N1,N2,NN1,2,\dots,\sqrt N,\lfloor\frac N1\rfloor,\lfloor\frac N2\rfloor,\dots\lfloor\frac N{\sqrt N}\rfloor。于是复杂度为 O(i=1Ni+i=1NNi)=O(i=1NNi)=O(1NNxdx)=O(N34)O\left(\sum_{i=1}^{\sqrt N}\sqrt i+\sum_{i=1}^{\sqrt N}\sqrt{\left\lfloor\frac Ni\right\rfloor}\right)=O\left(\sum_{i=1}^{\sqrt N}\sqrt{\left\lfloor\frac Ni\right\rfloor}\right)=O\left(\int_1^{\sqrt N}\sqrt{\frac Nx}{\rm d}x\right)=O\left(N^{\frac34}\right) 第一步等号是因为后面的求和项显然比左边的大,所以在大 OO 符号中左边的可以省略。第二步等号为积分近似。
但是我们不能满足于此。我们发现如果对于较小的 nn 仍然 O(n)O(\sqrt n) 计算 S{\bf S} 是不明智的,因为大部分情况下我们可以 O(n)O(n) 预处理出 S(1),S(2),S(n){\bf S}(1),{\bf S}(2),\dots{\bf S}(n)(利用线性筛一类)。我们如果预处理出 1Nc(c>12)1\dots N^c(c>\frac12) 的答案,那么需要递归计算的只剩下N1,N2,NN1c\lfloor\frac N1\rfloor,\lfloor\frac N2\rfloor,\dots\lfloor\frac N{N^{1-c}}\rfloor,于是复杂度变成
O(Nc+i=1N1cNi)=O(Nc+1N1cNxdx)=O(Nc+N112c)O\left(N^c+\sum_{i=1}^{N^{1-c}}\sqrt{\left\lfloor\frac Ni\right\rfloor}\right)=O\left(N^c+\int_1^{N^{1-c}}\sqrt{\frac Nx}{\rm d}x\right)=O\left(N^c+N^{1-\frac12 c}\right)
c=23c=\frac23 时复杂度最优,为 O(N23)O(N^{\frac23})
对于记忆化:可以使用 map,但会导致复杂度多一个 log\log
更好的做法是,由于递归调用的 nn 总是某个 Nx\lfloor\frac Nx\rfloor,并且 x>n13x>n^{\frac13} 的时候都会直接查预处理的表,所以可以直接记 Ans[x] 表示 Nx\lfloor\frac Nx\rfloor 的答案。详细代码例题中会给出。
对于计算 i=1n(fg)(i)\sum_{i=1}^n({\bf f*g})(i),由于后面还有 O(n)O(\sqrt n) 的递归复杂度,所以这个东西只要在 O(n)O(\sqrt n) 时间算完就不影响杜教筛复杂度;或者因为 nn 都是 Nx\lfloor\frac Nx\rfloor,所以这个也可以套一层杜教筛。i=1ng(i)\sum_{i=1}^n{\bf g}(i) 也类似,因为要计算的 nn 都是某个 Nx\lfloor\frac Nx\rfloor,所以这个 g\bf g 的前缀和也可以再套一层杜教筛qaq。

2.例题

1.P4213 【模板】杜教筛(Sum)

Description

给定 n2311n\leq 2^{31}-1,求:Sφ(n)=i=1nφ(n){\bf S}_{\varphi}(n)=\sum_{i=1}^n\varphi(n),以及 Sμ(n)=i=1nμ(n){\bf S}_{\mu}(n)=\sum_{i=1}^n\mu(n)

Solution

首先两个答案一定在 long longint 范围内,因为 0φ(n)n,1μ(n)10\leq\varphi(n)\leq n,-1\leq\mu(n)\leq1
杜教筛的难点在于,给定一个 f(n){\bf f}(n),要找一个合适的函数 g(n){\bf g}(n) 使 g,fg{\bf g},{\bf f*g} 的前缀和都可以快速计算。
对于 φ(n)\varphi(n),我们知道 φ=μid,φ1=id\varphi=\mu*{\bf id},\varphi*{\bf 1}={\bf id}。所以选取 g(n)=1{\bf g}(n)=1 即可,此时 (fg)(n)=n({\bf f*g})(n)=n,很容易求和。
对于 μ(n)\mu(n),选取 g(n)=1{\bf g}(n)=1 也可,此时 (fg)=ϵ(n)=[n=1]({\bf f*g})=\epsilon(n)=[n=1],也很容易求和。

Code

下面给出求 Sφ{\bf S}_\varphi 的代码:
CPP
typedef long long LL;
const int maxn = 2147483647;
const int maxm = 2000000;

LL S1[maxm], S2[1300];
bool vis[1300];
int N;

LL S(int n) {
  if (n < maxm) return S1[n];
  int x = N / n; // 如果存在某个 x 使得 n = floor(N / x),
                 // 选 x = floor(N / n) 一定可以。
  if (vis[x]) return S2[x];
  vis[x] = true;
  LL &ans = S2[x];
  ans = (LL)n * (n + 1) / 2; // 对 (f*g)(n) = n 求和
  for (int i = 2, j; i <= n; i = j + 1) {
    j = n / (n / i);
    ans -= (j - i + 1) * S(n / i);
  }
  return ans;
}
代码中 maxn, maxm, 1300 分别是 N,N23,N13N,N^{\frac23},N^{\frac13} 的最大值,S1[i] 在执行之前应预处理,是当 nN23n\leq N^{\frac23} 时的 Sφ(n){\bf S}_\varphi(n)S2[x],vis[x] 用来记忆化 Sφ(Nx){\bf S}_\varphi(\lfloor\frac Nx\rfloor)
至于代码中的第一句注释,则是因为 Nn\lfloor\frac Nn\rfloor 是使得 xnN    Nxnxn\leq N\iff\lfloor\frac Nx\rfloor\geq n 的最大正整数 xx 。如果这个 xx 还不满足 Nx=n\lfloor\frac Nx\rfloor=n 的话,就不可能存在其他 xx 了。

2. P3768 简单的数学题

Description

给定 nn,求 i=1nj=1n(ijgcd(i,j))\sum_{i=1}^n\sum_{j=1}^n(ij\gcd(i,j))pp 取模。n,m1010,5×108p1.1×109n,m\leq10^{10},5\times10^8\leq p\leq1.1\times10^9pp 是质数。时限 6s。

Solution

首先有 i=1nj=1n(ijgcd(i,j))=i=1nj=1n(ijdi,djφ(d))=d=1nφ(d)(1in,dii)(1jn,djj)=d=1nd2φ(d)S(nd)2\begin{aligned}&\sum_{i=1}^n\sum_{j=1}^n(ij\gcd(i,j))\\=&\sum_{i=1}^n\sum_{j=1}^n\left(ij\sum_{d\mid i,d\mid j}\varphi(d)\right)\\=&\sum_{d=1}^{n}\varphi(d)\left(\sum_{1\leq i\leq n,d\mid i}i\right)\left(\sum_{1\leq j\leq n,d\mid j}j\right)\\=&\sum_{d=1}^{n}d^2\varphi(d)S\left(\left\lfloor\frac nd\right\rfloor\right)^2\end{aligned} 式中 S(k)=i=1ki=k(k+1)2S(k)=\sum_{i=1}^k i=\frac{k(k+1)}2。第一步等式是因为 dkφ(d)=k\sum_{d\mid k}\varphi(d)=k。第二步等式是交换了求和顺序,把对 dd 的求和放到最外层。第三步等式是把两个括号里的公因数 dd 提出来。
根据老套路,我们数论分块,并对每一块的 d2φ(d)d^2\varphi(d) 求区间和。
考虑使用杜教筛计算两个区间和相减。但是一个问题是时间复杂度。
假设我们已经有了函数 LL S(LL n) 用来求 d2φ(d)d^2\varphi(d) 的前缀和,那么接下来应该这样:
CPP
for (int i = 1, j; i <= n && i <= m; i = j + 1) {
  j = n / (n / i);
  LL t = Sum(n / i);
  ans = (ans + (S(j) - S(i - 1)) * t % p * t % p) % p;
}
可以发现 j 始终是某个 nx\lfloor\frac nx\rfloor ,而 i-1 就是上一次的 j ,自然也是某个 nx\lfloor\frac nx\rfloor 。从而恰好用到了杜教筛所有的递归计算,仍然只有 O(n23)O(n^{\frac23}) 的复杂度。
第二个问题是对于 f(n)=n2φ(n){\bf f}(n)=n^2\varphi(n),如何找到合适的 g{\bf g}
考虑在数论函数的狄利克雷卷积之外定义点乘 fg{\bf f\cdot g},指逐项相乘,即 (fg)(n)=f(n)g(n)({\bf f\cdot g})(n)={\bf f}(n){\bf g}(n);定义函数 f(n){\bf f}(n) 是完全积性函数,当且仅当对于所有的 n,mn,m 都有 f(nm)=f(n)f(m){\bf f}(nm)={\bf f}(n){\bf f}(m)。像 ϵ(n)=[n=1],idk(n)=nk\epsilon(n)=[n=1],{\bf id}^k(n)=n^k 都在此列。

引理 2.1

f{\bf f} 是完全积性函数,g,h{\bf g, h} 是数论函数,则 (fg)(fh)=f(gh)({\bf f\cdot g})*({\bf f\cdot h})={\bf f}\cdot({\bf g*h})
证明是很显然的:
((fg)(fh))(n)=dnf(d)g(d)f(nd)h(nd)=f(n)dng(d)h(nd)=(f(gh))(n)\begin{aligned}&\left(({\bf f\cdot g})*({\bf f\cdot h})\right)(n)\\=&\sum_{d\mid n}{\bf f}(d){\bf g}(d){\bf f}\left(\frac nd\right){\bf h}\left(\frac nd\right)\\=&{\bf f}(n)\sum_{d\mid n}{\bf g}(d){\bf h}\left(\frac nd\right)\\=&\left({\bf f}\cdot({\bf g*h})\right)(n)\end{aligned}
由此,对于 f(n)=n2φ(n){\bf f}(n)=n^2\varphi(n),即 f=id2φ{\bf f}={\bf id}^2\cdot\varphi,可取 g=id21{\bf g}={\bf id}^2\cdot{\bf 1},则根据上述引理有 fg=id2(φ1){\bf f*g}={\bf id}^2\cdot(\varphi*{\bf 1}),即 fg=id3{\bf f*g}={\bf id}^3
所以令 g(n)=n21=n2{\bf g}(n)=n^2\cdot1=n^2,则立得 S(n)=i=1ni3i=2ni2S(ni){\bf S}(n)=\sum_{i=1}^ni^3-\sum_{i=2}^ni^2{\bf S}\left(\left\lfloor\frac ni\right\rfloor\right) 至于如何对 i2,i3i^2,i^3 求和,我们有 i=1ni3=n2(n+1)24\sum_{i=1}^ni^3=\frac{n^2(n+1)^2}4i=1ni2=n(n+1)(2n+1)6\sum_{i=1}^ni^2=\frac{n(n+1)(2n+1)}6
具体代码作为练习(雾),其实和上面的 φ(n)\varphi(n) 的杜教筛是类似的。

3. BZOJ4176 Lucas的数论

这是权限题。

Description

给定 nn,求 i=1nj=1nd(ij)\sum_{i=1}^n\sum_{j=1}^n{\bf d}(ij)d(k){\bf d}(k)kk 的约数个数。
n109n\leq10^9。简化版是[SDOI2015]约数个数和

Solution

对于 d(ij){\bf d}(ij),考虑某个 dijd\mid ij 来说,令 a=igcd(i,d),b=dgcd(i,d)a=\frac i{\gcd(i,d)},b=\frac d{\gcd(i,d)},显然 ab,ai,bja\perp b,a\mid i,b\mid j (前两个显然,最后一个是因为bgcd(i,d)ijbajbjb\gcd(i,d)\mid ij\Rightarrow b\mid aj\Rightarrow b\mid j 。最后一步是因为 aba\perp b )。另外,任意给定两个数 a,ba,b 使得 ab,ai,bja\perp b,a\mid i,b\mid j 都有 d=iabijd=\frac iab\mid ij ,且 igcd(i,d)=a,dgcd(i,d)=b\frac i{\gcd(i,d)}=a,\frac d{\gcd(i,d)}=b。 由此可知 dij1=ai,bj,ab1=ai,bj[ab]\sum_{d\mid ij}1=\sum_{a\mid i,b\mid j,a\perp b}1=\sum_{a\mid i,b\mid j}[a\perp b]
所以 ans=i=1nj=1nd(ij)=i=1nj=1naibj[ab]=i=1nj=1naibjda,dbμ(d)=d=1nμ(d)(daain1)(dbbjn1)=d=1nμ(d)(a=1ndnda)2\begin{aligned}ans=&\sum_{i=1}^n\sum_{j=1}^n{\bf d}(ij)\\=&\sum_{i=1}^n\sum_{j=1}^n\sum_{a\mid i}\sum_{b\mid j}[a\perp b]\\=&\sum_{i=1}^n\sum_{j=1}^n\sum_{a\mid i}\sum_{b\mid j}\sum_{d\mid a,d\mid b}\mu(d)\\=&\sum_{d=1}^n\mu(d)\left(\sum_{d\mid a}\sum_{a\mid i\leq n}1\right)\left(\sum_{d\mid b}\sum_{b\mid j\leq n}1\right)\\=&\sum_{d=1}^n\mu(d)\left(\sum_{a=1}^{\lfloor\frac nd\rfloor}\left\lfloor\frac {\lfloor\frac nd\rfloor}a\right\rfloor\right)^2\end{aligned}F(n)=i=1nni=i=1nijn1=t=1nd(t)F(n)=\sum_{i=1}^n\left\lfloor\frac ni\right\rfloor=\sum_{i=1}^n\sum_{ij\leq n}1=\sum_{t=1}^n{\bf d}(t)ans=d=1nμ(d)F(nd)2ans=\sum_{d=1}^n\mu(d)F\left(\left\lfloor\frac nd\right\rfloor\right)^2dd 数论分块,则需要快速求出 μ(d)\mu(d) 的前缀和与 F(nd)F\left(\left\lfloor\frac nd\right\rfloor\right)。前者可以直接杜教筛;后者可以借鉴杜教筛的思想。
考虑到单次计算 F(n)F(n) 复杂度为 O(n)O(\sqrt n)(数论分块),而预处理 F(1)F(n)F(1)\dots F(n) 复杂度是 O(n)O(n)(因为可以线性筛出 d{\bf d},则可以预处理出 F(1)F(n23)F(1)\dots F(n^{\frac23}),后面的 FF 依次 O(n)O(\sqrt n) 算,复杂度仍然是 O(n23)O(n^{\frac23})
虽然实际上这道题不预处理的话 O(n34)O(n^{\frac34}) 也能过,但是无所谓了qaq。

4. 奇怪的题目

Description

给定 nn ,求 i=1n(μ2(idμ))(i)\sum_{i=1}^n(\mu^2*({\bf id}\cdot\mu))(i)
其中 n109n\leq10^9μ2(n)=(μ(n))2\mu^2(n)=(\mu(n))^2

Solution

f=μ2(idμ){\bf f}=\mu^2*({\bf id}\cdot\mu),则 idf=(id(idμ))μ2=μ2{\bf id}*f=({\bf id}*({\bf id}\cdot\mu))*\mu^2=\mu^2。所以取 g(n)=n{\bf g}(n)=n,因此 S(n)=i=1nμ2(i)i=2niS(ni){\bf S}(n)=\sum_{i=1}^n\mu^2(i)-\sum_{i=2}^ni{\bf S}\left(\left\lfloor\frac ni\right\rfloor\right) 剩下的就是如何计算 i=1nμ2(i)\sum_{i=1}^n\mu^2(i)
可以发现 μ2(i)=[i不含平方因子]\mu^2(i)=[i\text{不含平方因子}]。所以定义 s(i)=maxd2id{\bf s}(i)=\max_{d^2\mid i}d,则 μ2(i)=[s(i)=1]\mu^2(i)=[{\bf s}(i)=1]
容易发现 d2i    ds(i)d^2\mid i\iff d\mid{\bf s}(i), 所以 i=1nμ2(i)=i=1n[s(i)=1]=i=1nd2iμ(d)=d=1nμ(d)nd2\sum_{i=1}^n\mu^2(i)=\sum_{i=1}^n[{\bf s}(i)=1]=\sum_{i=1}^n\sum_{d^2\mid i}\mu(d)=\sum_{d=1}^{\lfloor\sqrt n\rfloor}\mu(d)\left\lfloor\frac n{d^2}\right\rfloor 可以暴力枚举 dd,在 O(n)O(\sqrt n) 时间内求出。由于杜教筛本来就有 O(n)O(\sqrt n) 的计算,这并不会增加复杂度。

3.贝尔级数

有的时候我们不太容易找到杜教筛的合适的 g{\bf g},这时候有一个很厉害的东西:贝尔级数。
(Warning: 以下要求大致了解生成函数相关)

3.1 定义

对于积性函数 f(n){\bf f}(n) ,定义 f{\bf f}pp 的贝尔级数为 fp(x)=i=0f(pi)xi{\bf f}_p(x)=\sum_{i=0}^{\infty}{\bf f}(p^i)x^i 例如 ϵp(x)=1,1p(x)=11x,idpk(x)=11pkx,μp(x)=1x,dp(x)=1(1x)2,φp(x)=1x1px\epsilon_p(x)=1,{\bf 1}_p(x)=\frac1{1-x},{\bf id}^k_p(x)=\frac1{1-p^kx},\mu_p(x)=1-x,{\bf d}_p(x)=\frac1{(1-x)^2},\varphi_p(x)=\frac{1-x}{1-px}
一个很好的性质是(实际上就是把狄利克雷卷积变成了一般卷积)
(fg)p(x)=fp(x)gp(x)({\bf f*g})_p(x)={\bf f}_p(x){\bf g}_p(x)
接下来我们就要生拼硬凑出一些奇怪的例题了:

3.2 例题

令积性函数 f{\bf f} 满足 f(pc)=pc+[c>0](1)c{\bf f}(p^c)=p^c+[c>0](-1)^c,求 f{\bf f} 的前缀和。
可以发现 fp(x)=1+i=0(pixi+(1)ixi)=11px+11+x1{\bf f}_p(x)=-1+\sum_{i=0}^{\infty}\left(p^ix^i+(-1)^ix^i\right)=\frac1{1-px}+\frac1{1+x}-1, 所以取 gp(x)=(1px)(1+x){\bf g}_p(x)=(1-px)(1+x),即得 (fg)p(x)=1+x+1px(1px)(1+x)=1+px2({\bf f*g})_p(x)=1+x+1-px-(1-px)(1+x)=1+px^2 所以问题转化成了如何求 g{\bf g} 的前缀和,以及如何求 hp(x)=1+px2{\bf h}_p(x)=1+px^2 的前缀和。
显然可知 (1px)(1-px) 对应 idμ{\bf id}\cdot\mu,而 (1+x)(1+x) 对应 μ2\mu^2。(指 μ2(n)=(μ(n))2=μ(n)\mu^2(n)=(\mu(n))^2=|\mu(n)|)。
所以 g=(idμ)μ2{\bf g}=({\bf id}\cdot\mu)*\mu^2,其前缀和可以通过之前的那道“奇怪的题目”的做法求出。
而对于 h(n){\bf h}(n) 的前缀和,可以发现只有 nn 是完全平方数,且每个质因数的指数都是 2 (等价于 μ(n)0\mu(\sqrt n)\neq0)时 h(n)=n{\bf h}(n)=\sqrt n,其他时候 h(n)=0{\bf h}(n)=0。所以很显然的, i=1nh(i)=i=1niμ2(i)\sum_{i=1}^n{\bf h}(i)=\sum_{i=1}^{\lfloor\sqrt n\rfloor}i\mu^2(i) 枚举 ii 即可在 O(n)O(\sqrt n) 时间内算出。所以本题解决了,复杂度是 O(n23)O(n^{\frac23})

4.总结

本篇文章,是一位在 OI 中数学方面小有名气的选手无私的馈赠。五道杜教筛例题,涵盖了杜教筛从入门到进阶的大部分套路。你可以通过这篇文章,对杜教筛进行较为深入的了解。详细的复杂度证明、精心挑选的例题和各种不同的套路与 trick,能让你对杜教筛有一个较为全面的掌握。作者相信,这篇漂亮的博客,可以给拼搏于 OI 的逐梦之路上的你,提供一个有力的援助。
本文在读者已经掌握莫比乌斯反演的基础上讲述了杜教筛,并提出了若干例题,涵盖了部分杜教筛题目的套路;既可以作为杜教筛的入门文章,又可以让部分选手更进一步地了解杜教筛,更是一篇不错的杜教筛复习博客。

评论

45 条评论,欢迎与作者交流。

正在加载评论...