筛筛筛

前言

最不喜欢的一集。数论感觉对我而言还是太神秘了。

线性筛

没啥好说的,反正啥积性函数都能筛,这就导致所有筛都得是亚线性的,不然一点优势都没有。

接下来几乎所有的筛法都是解决积性函数单点询问前缀和的问题。为啥不解决单点询问积性函数值呢,因为你基本上一分解质因数就啥都没了。

杜教筛

为了求 \(S_f\),我们给它卷上另一个构造的函数 \(g\)

\[\begin{aligned} S_{f*g}(n)&=\sum_{i=1}^n\sum_{d\mid i}f(\frac id)g(d)\\ &=\sum_{d=1}^ng(d)\sum_{x=1}^{\lfloor\frac nd\rfloor}f(x)\\ &=\sum_{d=1}^ng(d)S_f(\lfloor\frac nd\rfloor) \end{aligned} \]

考虑移项。

\[S_f(n)=\frac{1}{g(1)}(S_{f*g}(n)-\sum_{d=2}^ng(d)S_f(\lfloor\frac nd\rfloor)) \]

右边那个和式可以数论分块。

所以,我们构造的 \(g\) 要满足,可以快速计算 \(S_g,S_{f*g}\)\(g(1)\neq 0\)

下面来分析一下复杂度。首先所有能够被用到的 \(\lfloor\frac nd\rfloor\) 构成的集合其实就是 \(S=\{\lfloor\frac nd\rfloor\mid d\in N\}\),这是因为 \(\lfloor\frac{\lfloor\frac nd\rfloor}x\rfloor=\lfloor\frac n{dx}\rfloor\)

所以我们总的复杂度其实就是计算 \(S\) 所有元素的 \(S_{f*g},S_f(n)\)。我们这里假设计算 \(S_{f*g}(n),S_g(n)\) 都是 \(O(1)\) 的。

考虑现在正在计算 \(S_f(n)\),这需要一次数论分块,复杂度 \(O(\sqrt{n})\)

因此总复杂度是 \(T(n)=O(\sqrt{n})+\sum_{i=1}^{\sqrt{n}}O(\sqrt{i})+\sum_{i=1}^{\sqrt{n}}O(\sqrt{\frac ni})=O(n^{\frac 34})\)

如果预处理了 \(1\dots m(m\ge\sqrt{n})\)\(S_f\),那么复杂度变为 \(O(T_0(m)+\frac n{\sqrt{m}})\)。当 \(T_0(m)=O(m)\) 时取 \(m=n^\frac 23\) 得到最优复杂度 \(O(n^\frac 23)\)

事实上,只要我们有方法知道 \(f,g,f*g\) 中任意两个在根号处的位置,都可以通过杜教筛知道另一个函数。

例题

让我们练练手吧!

  • 试计算 \(S(n)=\sum_{i=1}^n\varphi(i)i^2,n\le 10^9\)

你需要知道的是,如果 \(h\) 是完全积性函数,那么 \((fh)*(gh)=(f*g)h\)

我们要求的函数是 \(\varphi id_2\),考虑给它再卷上一个 \(id_2\)

\[(\varphi id_2)*id_2=(\varphi id_2)*(1id_2)=(\varphi*1)id_2=id_3 \]

后面就是套杜教筛就行了。

类似地,\(\mu id_k,\varphi id_k\) 都可以计算。

  • 试计算 \(S(n)=\mu^2*(\mu id)\)

\[\mu^2*(\mu id)*id=\mu^2*((\mu id)*id)=\mu^2*\epsilon=\mu^2 \]

问题变成了 \(\mu^2\) 的前缀和,这是一个重要的问题,叫做无平方因子数。

我们称一个数是无平方因子数,当且仅当它质因数分解后,所有次幂都 \(\le 1\)。事实上 \([x 是无平方因子数]=\mu^2(x)\)

考虑求无平方因子数个数的前缀和 \(f(n)\),设另一函数 \(g(x)=[最大的 p 满足 p^2\mid x]\)

那么我们要求的就是 \(f(n)=\sum_{x=1}^n[g(x)=1]=\sum_{x=1}^n\sum_{d\mid g(x)}\mu(d)\)

\(d\mid g(x)\iff d^2\mid x\),所以 \(f(n)=\sum_{d=1}^n\mu(d)\lfloor\frac n{d^2}\rfloor\)

也就是说 \(\sum_{x=1}^n\mu^2(x)=\sum_{d=1}^{\sqrt{n}}\mu(d)\lfloor\frac n{d^2}\rfloor\)

PN 筛

听说算是杜教筛的扩展。

我们定义 Powerful Number \(x\),为质因数分解之后,所有次幂都 \(\ge 2\) 的数。

一个性质是,所有 PN 可以被表示成 \(a^2b^3\) 形式,这个只需要根据次幂的奇偶性决定放到 \(a\) 还是 \(b\) 里头。

这样 PN 的个数就可以估计了。

\[\int_0^{\sqrt{n}}\sqrt[3]{\frac n{x^2}}\text{d}x=O(\sqrt{n}) \]

为了找到所有的 PN,我们可以先筛出 \(\sqrt{n}\) 内的质数,然后 dfs 搜索指数,这样每个数只会被搜到一次,复杂度为 \(O(\sqrt{n})\)

接下来说 PN 筛的部分。

我们要筛的函数 \(f\) 要是积性函数,并且构造另一个函数 \(g\),满足 \(g\) 是积性函数,\(g(p)=f(p),p\in Prime\)\(g\) 的前缀和方便计算。

构造另一个函数 \(h=f/g,h(1)=1\),换句话说 \(f=g*h\),对于素数 \(p\)\(f(p)=g(p)h(1)+g(1)h(p)\Rightarrow h(p)=0\)

又由 \(h\) 是积性函数,我们知道它只在 PN 处不为 \(0\)

\[\begin{aligned} S_f(n)&=\sum_{x=1}^n\sum_{d\mid x}g(\frac xd)h(d)\\ &=\sum_{d=1}^nh(d)S_g(\lfloor\frac nd\rfloor)\\ &=\sum_{d=1,d\in PN}h(d)S_g(\lfloor\frac nd\rfloor) \end{aligned} \]

清算复杂度,我们可以分成计算 \(S_g\) 的根号部分,计算 \(h(d)\),搜索部分三部分。

对于计算 \(S_g\),我们可以使用杜教筛,有公式当然用公式。

对于计算 \(h(d)\),我们只需要计算 \(h(p^a)\) 处的值,有公式用公式,没有公式由 \(f=g*h\) 得到 \(h(p^a)=\frac{1}{g(1)}(f(p^a)-\sum_{i=1}^ag(p^i)h(p^{a-i}))\)。这部分复杂度上界是 \(O(\frac{\sqrt{n}}{\log n}\log n\log n)=O(\sqrt{n}\log n)\),有具体优化空间。

对于搜索,这部分是 \(O(\sqrt{n})\)

所以,PN 筛复杂度大约是 \(O(\sqrt{n})\)

reference

command_block

posted @ 2024-06-18 20:30  PYD1  阅读(12)  评论(0)    收藏  举报