算法学习笔记(28): 筛法

筛法

冷静分析:CMD 的博客

线性筛

线性筛是个好东西。一般来说,可以在 O(n) 内处理几乎所有的积性函数。

还可以 O(n) 找出所有的质数……(废话


杜教筛

放在偏序关系 (Z,|) 中卷积……

如何快速的求 S(n)=i=1nf(i)

如果能够找到一个函数 g

i=1n(fg)(i)=i=1nd|if(id)g(d)=d=1ng(d)i=1ndf(i)=d=1ng(d)S(nd)

那么可以得出:

g(1)S(n)=i=1n(fg)(i)d=2ng(d)S(nd)

这样我们就可以通过整除分块快速的求出 g(1)S(n) 了。

当然,需要有很严苛的前提:

  • fg 的前缀和是可以快速求的。

  • g 的前缀和也是可以快速求的。

  • 这里的快速应该是 O(1),如果是 O(logn) 估计也没关系。

其时间复杂度大概是在 O(n23) 的,如果不预处理小块的话应该是 O(n34) 的。


例题

  1. 快速求 i=1nj=1nφ(gcd(i,j))

  2. 快速求 i=1nj=1nijgcd(i,j)

例二中有一个很好的东西,点乘。

其定义有:(fg)(n)=f(n)g(n)

h完全积性函数时,有 (fh)(gh)=(fg)h

这里列出一些基本的组合:

  • μidk

    ((μidk)idk)(n)=d|nμ(d)dk(nd)k=nk+1d|nμ(d)=ε(n)

  • φidk

    (φidk)idk=I,推导同上。


Min25 筛

本质是对线性筛的扩展……

为了方便,声明一些符号:

  • P 代表质数集合。

  • Pi 表示第 i 个质数。

  • minp(i) 表示 i 的最小质因数。

还是求 i=1nf(i)。可以用 Min25 筛需要满足一些条件:

  • f(i) 是一个低阶多项式。

  • f(pk) 可以快速的求解。

现在考虑把每一阶分别计算。

TODO


PN 筛

首先定义 Powerful Number

一个数是 Powerful Number 当其质因数分解中 n=i=1kpicii(ci>1)

由于一个 Powerful Number 可以表示为一个数的平方和一个数的立方,所以 n 以内的 PN 数一共有 O(n) 个。

现在假设要求 F(n)=i=1nf(i)

需要找到函数 g 满足:

  • 为积性函数。

  • 易求前缀和。

  • 在质数 p 处取值与原函数相等:f(p)=g(p)

G(n)=i=1ng(n)

先构造函数 h 满足 hg=f

于是将卷积展开:

F(n)=i=1nf(i)=i=1nd|ih(d)g(id)=d=1ni=1ndh(d)g(i)=d=1nh(d)i=1ndg(i)=d=1nh(d)G(nd)

怎么可以套数论分块?

由于积性函数相乘任然为积性函数,所以可知 h(1)=1

所以对于质数 p,有 f(p)=g(1)h(p)+g(p)h(1)=h(p)+g(p)

由于 f(p)=g(p),所以可知 h(p)=0

根据积性函数的性质,可以推导出 h(n) 只在 nPN 数的时候才可能不为 0

所以原式变为:

F(n)=d is PNnh(d)G(nd)

这样,我们只需要求出 O(n)h(d) 的取值,以及快速算出 G(x) 的取值即可。

那么我们考虑如何求解 h(d)

根据 f=gh

f(pc)=i=0cg(pi)h(pci)

稍微移项可以得到:

g(1)h(pc)=f(pc)i=1cg(pi)h(pci)h(pc)=f(pc)i=1cg(pi)h(pci)

于是可以枚举所有的 p 以及 c 求出 h(pc) 即可。

此时 p 的个数视作 O(n),而 c 的界为 O(logn),有由于是 logn 转移,所以这部分复杂度为 O(nlogn2),而且这个上界很宽松。

但是如果我们直接推导出 h(pc) 仅与 pc 有关的计算公式,那么可能更加优秀,复杂度一般为 O(nlogn)

所以总的复杂度一般为 O(n+nlogn)=O(nlogn)。非常的优秀。

然而根据 CMD 的博客,硬上的复杂度实际上是 O(n/logn)……更加优秀了。

不过有些情况下,利用 PN 筛可能需要套一个杜教筛,毕竟我们除了 h(pc) 还需要求出 G(x) 的前缀和。

此时需要加上杜教筛的复杂度,可以认为是 O(n23) 的。

posted @   jeefy  阅读(42)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示