我也不知道什么是"莫比乌斯反演"和"杜教筛"

upd:发现这篇文章里面似乎有很多细节上的错误,如果还有错误的话在cnblogs下评论吧,我会改的QwQ,cnblogs戳这里

upd:正在写一篇复习向的文章,之后贴链接,可以作为这篇文章的一个补充。
upd:写好啦,戳这里。新写的这篇复习向文章QwQ,可以当做一个补充来看吧。不过新写的文章也有我新的理解吧。

Part0

最近一直在搞这些东西
做了将近20道题目吧
也算是有感而发
写点东西记录一下自己的感受

如果您真的想学会莫比乌斯反演和杜教筛,请拿出纸笔,每个式子都自己好好的推一遍,理解清楚每一步是怎么来的,并且自己好好思考。

Part1莫比乌斯反演

莫比乌斯反演啥都没有,就只有两个式子(一般只用一个)
原来我已经写过一次了,再在这里写一次
就只写常用的那个吧

基本的公式


对于一个函数 f ( x ) f(x) f(x)
g ( x ) = ∑ x ∣ d f ( d ) g(x)=\sum_{x|d}f(d) g(x)=xdf(d)
那么
f ( x ) = ∑ x ∣ d μ ( d x ) g ( d ) f(x)=\sum_{x|d}\mu(\frac{d}{x})g(d) f(x)=xdμ(xd)g(d)


这个有什么用?
似乎太有用了一点

随手搞道题目来说吧


∑ i = 1 n ∑ j = 1 m [ g c d ( i , j ) = 1 ] \sum_{i=1}^n\sum_{j=1}^m[gcd(i,j)=1] i=1nj=1m[gcd(i,j)=1]

这个东西很直接,
所以我们设 f ( x ) = ∑ i = 1 n ∑ j = 1 m [ g c d ( i , j ) = x ] f(x)=\sum_{i=1}^n\sum_{j=1}^m[gcd(i,j)=x] f(x)=i=1nj=1m[gcd(i,j)=x]
g ( x ) = ∑ x ∣ d f ( d ) g(x)=\sum_{x|d}f(d) g(x)=xdf(d)
根据莫比乌斯反演可以得到
f ( 1 ) = ∑ 1 ∣ d μ ( d 1 ) g ( d ) = ∑ i = 1 n μ ( i ) g ( i ) f(1)=\sum_{1|d}\mu(\frac{d}{1})g(d)=\sum_{i=1}^n\mu(i)g(i) f(1)=1dμ(1d)g(d)=i=1nμ(i)g(i)
g ( x ) g(x) g(x)是什么东西?
g ( x ) = ∑ i = 1 n ∑ j = 1 m [ x ∣ g c d ( i , j ) ] g(x)=\sum_{i=1}^n\sum_{j=1}^m[x|gcd(i,j)] g(x)=i=1nj=1m[xgcd(i,j)]
直接把 x x x除到上面去
g ( x ) = ∑ i = 1 n / x ∑ j = 1 m / x [ 1 ∣ g c d ( i , j ) ] g(x)=\sum_{i=1}^{n/x}\sum_{j=1}^{m/x}[1|gcd(i,j)] g(x)=i=1n/xj=1m/x[1gcd(i,j)]
[ 1 ∣ g c d ] [1|gcd] [1gcd]显然成立的
所以 g ( x ) = [ n x ] [ m x ] g(x)=[\frac{n}{x}][\frac{m}{x}] g(x)=[xn][xm]
可以 O ( 1 ) O(1) O(1)计算
所以, f ( 1 ) f(1) f(1)可以 O ( n ) O(n) O(n)计算


一起推下式子

莫比乌斯反演的套路太多了

我们再来看两道题目
Crash的数字表格
jzptab

这两题按照顺序看嗷

具体的过程直接看我博客里面写的东西

我们发现这两道题一模一样
但是下面的那道题目可以做到单次询问 O ( n ) O(\sqrt n) O(n )

他多干了什么???
这个问题,我们自己再来重新推一下
不过找个容易点的东西


∑ i = 1 n ∑ j = 1 m g c d ( i , j ) \sum_{i=1}^n\sum_{j=1}^mgcd(i,j) i=1nj=1mgcd(i,j)

这个肯定没有前面我给的例子的莫比乌斯反演那么直接
但是我们观察一下, g c d gcd gcd的取值有哪些??
1 ~ n 1~n 1n(假设 n &lt; m n&lt;m n<m)
那么,我们可以把 g c d gcd gcd相同的项合并

所以,我们枚举 g c d gcd gcd的值
∑ d = 1 n d ∑ i = 1 n ∑ j = 1 m [ g c d ( i , j ) = d ] \sum_{d=1}^nd\sum_{i=1}^n\sum_{j=1}^m[gcd(i,j)=d] d=1ndi=1nj=1m[gcd(i,j)=d]
后面的那一部分是不是想到了前面推出的东西???
所以先把 d d d直接除上去
∑ d = 1 n d ∑ i = 1 n / d ∑ j = 1 m / d [ g c d ( i , j ) = 1 ] \sum_{d=1}^nd\sum_{i=1}^{n/d}\sum_{j=1}^{m/d}[gcd(i,j)=1] d=1ndi=1n/dj=1m/d[gcd(i,j)=1]
n / d n/d n/d m / d m/d m/d不要想太多,你就当成 x x x y y y
∑ i = 1 x ∑ j = 1 y [ g c d ( i , j ) = 1 ] \sum_{i=1}^{x}\sum_{j=1}^{y}[gcd(i,j)=1] i=1xj=1y[gcd(i,j)=1]
不就是上面推过的第一个例子??
= ∑ i = 1 x μ ( i ) [ x i ] [ y i ] =\sum_{i=1}^x\mu(i)[\frac{x}{i}][\frac{y}{i}] =i=1xμ(i)[ix][iy]

把这一截放回我们要求的式子里面去
∑ d = 1 n d ∑ i = 1 x μ ( i ) [ x i ] [ y i ] \sum_{d=1}^nd\sum_{i=1}^{x}\mu(i)[\frac{x}{i}][\frac{y}{i}] d=1ndi=1xμ(i)[ix][iy]
x , y x,y x,y还是写成原样吧
∑ d = 1 n d ∑ i = 1 n / d μ ( i ) [ n i d ] [ m i d ] \sum_{d=1}^nd\sum_{i=1}^{n/d}\mu(i)[\frac{n}{id}][\frac{m}{id}] d=1ndi=1n/dμ(i)[idn][idm]

是不是 n / d n/d n/d可以数论分块
而在计算后面的东西的时候, n / d i \frac{n/d}{i} in/d也可以数论分块??
所以这个时候的复杂度是 O ( n ) O(n) O(n)
与之相对应的就是上面Crash的数字表格 O ( n ) O(n) O(n)做法

可是,像下面那个 O ( n ) O(\sqrt n) O(n )是怎么做的呢?

那我们就继续推一步
我们是不是可以直接对 n i d \frac{n}{id} idn分块呢?
所以,我们设 T = i d T=id T=id i d id id换一下
∑ d = 1 n d ∑ i = 1 n / d μ ( i ) [ n T ] [ m T ] \sum_{d=1}^nd\sum_{i=1}^{n/d}\mu(i)[\frac{n}{T}][\frac{m}{T}] d=1ndi=1n/dμ(i)[Tn][Tm]
这个时候,比较关键的一步
T T T提出来
∑ T = 1 n [ n T ] [ m T ] ∑ d ∣ T d μ ( T d ) \sum_{T=1}^n[\frac{n}{T}][\frac{m}{T}]\sum_{d|T}d\mu(\frac{T}{d}) T=1n[Tn][Tm]dTdμ(dT)
为什么是这个??
我们来分析一波
首先每一个 T T T一定对应 [ n T ] [ m T ] [\frac{n}{T}][\frac{m}{T}] [Tn][Tm]
这一项之和 T T T有关,所以可以提出来

这个时候考虑对于每一个 T T T,什么样的 i i i d d d会给他产生贡献呢?
最显然的一点, d d d T T T的一个因数
看到上面的式子,我们不难发现会贡献一个 d d d的什么东西
后面的是什么? μ ( i ) \mu(i) μ(i)
继续想想,既然 T = i d T=id T=id,我们枚举了一个 T T T
又知道 d d d T T T的一个因子了,所以 i = T d i=\frac{T}{d} i=dT
所以,就有了上面把 T T T拿出来的式子

前面的东西看起来可以数论分块
但是这样子后面的东西怎么办?
不可能 O ( n ) O(\sqrt n) O(n )暴力枚举呀

没错,当然不需要暴力枚举
我们发现后面的东西也是一个积性函数(因为他是两个积性函数的狄利克雷卷积)
所以它是可以线性的筛出来的
到这里,前面对于 T T T数论分块
后面的前缀和可以 O ( n ) O(n) O(n)线性筛预处理出来
此时单次询问整体的复杂度就是 O ( n ) O(\sqrt n) O(n )

对了,不要思想江化
后面那个东西如果不能够直接线性筛
那就不要线性筛了,
只要复杂度允许,暴力筛也是很可以的


其实,如果我们继续观察,很容易知道一点:
∑ d ∣ T d μ ( T d ) = φ ( T ) \sum_{d|T}d\mu(\frac{T}{d})=\varphi(T) dTdμ(dT)=φ(T)

upd:原来底下的证明是假的,已经删掉了,这里用容斥的方法很容易证明,考虑到 μ \mu μ是容斥系数就可以很容易的知道上述式子的组合意义。

我们知道 ( 1 ∗ φ ) ( i ) = i (1*\varphi)(i)=i (1φ)(i)=i
还知道 ( 1 ∗ μ ) ( i ) = e (1*\mu)(i)=e (1μ)(i)=e
其中 1 1 1 f ( x ) = 1 f(x)=1 f(x)=1
e e e f ( x ) = [ x = 1 ] f(x)=[x=1] f(x)=[x=1]
i d id id f ( x ) = x f(x)=x f(x)=x

所以这个东西当然可以线性筛啦。


莫比乌斯反演差不多就到这里啦
我们经历的复杂度从 O ( n 2 ) O(n^2) O(n2)的暴力
推一步之后变成了 O ( n ) O(n) O(n)
再变成了 O ( n ) O(\sqrt n) O(n )

莫比乌斯反演的关键步骤也就是两步
首先是化简式子,写成莫比乌斯反演的形式
然后就是怎么处理前缀和,数论分块等东西的问题

这些能够解决好,莫比乌斯反演的题目就很好解决啦

Part2线性筛

当然是怎么各种线性筛东西啦

线性筛最重要的一点:
每个数一定,也只会,被他的最小质因子给筛到
说白点,比如说 72 = 2 ∗ 2 ∗ 2 ∗ 3 ∗ 3 72=2*2*2*3*3 72=22233
他就会被他的最小质因子给筛到
也就是 2 ∗ 36 2*36 236时被筛到

所以,一般线性筛如果要存储其他的东西来筛的话
一定是记录最小质因子的东西

大概的写一下几个积性函数:

μ \mu μ莫比乌斯函数

这个怎么筛应该都会吧

φ \varphi φ欧拉函数

怎么筛应该也很明显吧。

d d d约数个数

这个怎么筛?
考虑唯一分解定理:
x = ∏ p i a i x=\prod p_i^{ai} x=piai
那么 d ( x ) = ∏ ( a i + 1 ) d(x)=\prod (ai+1) d(x)=(ai+1)
记录一下最小质因子的个数
每次就先把原来的除掉,再把 + 1 +1 +1后的个数乘上就好啦

σ \sigma σ约数和

还是唯一分解定理
x = ∏ p i a i x=\prod p_i^{ai} x=piai
σ ( x ) = ∏ ( ∑ j = 0 a i p i j ) \sigma(x)=\prod (\sum_{j=0}^{ai}p_i^j) σ(x)=(j=0aipij)
记录一下最小质因子的上面那个式子的和
以及这个因子的 a i ai ai次幂
每次也是先除掉再乘上新的

a k a^k ak k k k次幂

把这个东西写进来,只是为了提醒一下
a k a^k ak这种东西是一个完全积性函数,也是可以丢进去筛的

i n v inv inv乘法逆元

没啥,一样的,乘法逆元也是完全积性函数
蛤,我知道可以 O ( n ) O(n) O(n)递推
只是写一下而已


我比较懒,不想把板子蒯过来
直接把ppl的链接给你们嗷(虽然他的代码风格我觉得很丑)

Part3杜教筛

来个栗子

线性筛 O ( n ) O(n) O(n)复杂度,美滋滋
好的,我知道了
来一个很 i n t e r e s t i n g interesting interesting的题目???

求 ∑ i = 1 n μ ( i ) 的 值 求\sum_{i=1}^n\mu(i)的值 i=1nμ(i)

我当然知道你会线性筛
所以 n &lt; = 1 0 9 n&lt;=10^9 n<=109

杜教筛是蛤?

比如说。。
我们现在要求一个积性函数 f ( i ) f(i) f(i)的前缀和 S ( i ) S(i) S(i)
也就是说 S ( n ) = ∑ i = 1 n f ( i ) S(n)=\sum_{i=1}^nf(i) S(n)=i=1nf(i)

现在很不好算呀
怎么办??

这个时候,就来杜教筛套路一波

我再来找个积性函数 g ( i ) g(i) g(i)(不知道是啥)
g g g f f f做一个卷积
( g ∗ f ) ( i ) = ∑ d ∣ i g ( d ) f ( i d ) (g*f)(i)=\sum_{d|i}g(d)f(\frac{i}{d}) (gf)(i)=dig(d)f(di)
再求一下卷积的前缀和
∑ i = 1 n ( g ∗ f ) ( i ) = ∑ i = 1 n ∑ d ∣ i g ( d ) f ( i d ) \sum_{i=1}^n(g*f)(i)=\sum_{i=1}^n\sum_{d|i}g(d)f(\frac{i}{d}) i=1n(gf)(i)=i=1ndig(d)f(di)
d d d给提出来
∑ d = 1 n g ( d ) ∑ d ∣ i f ( i d ) \sum_{d=1}^ng(d)\sum_{d|i}f(\frac{i}{d}) d=1ng(d)dif(di)
∑ d = 1 n g ( d ) ∑ i = 1 n / d f ( i ) \sum_{d=1}^ng(d)\sum_{i=1}^{n/d}f(i) d=1ng(d)i=1n/df(i)
∑ d = 1 n g ( d ) S ( n d ) \sum_{d=1}^ng(d)S(\frac{n}{d}) d=1ng(d)S(dn)
如果仔细想想
我们就会有这个式子:
g ( 1 ) S ( n ) = ∑ i = 1 n g ( i ) S ( n i ) − ∑ i = 2 n g ( i ) S ( n i ) g(1)S(n)=\sum_{i=1}^ng(i)S(\frac{n}{i})-\sum_{i=2}^ng(i)S(\frac{n}{i}) g(1)S(n)=i=1ng(i)S(in)i=2ng(i)S(in)
前面的东西是狄利克雷卷积
g ( 1 ) S ( n ) = ∑ i = 1 n ( g ∗ f ) ( i ) − ∑ i = 2 n g ( i ) S ( n i ) g(1)S(n)=\sum_{i=1}^n(g*f)(i)-\sum_{i=2}^ng(i)S(\frac{n}{i}) g(1)S(n)=i=1n(gf)(i)i=2ng(i)S(in)
如果狄利克雷卷积的前缀和非常好算的话
那么我们就可以对后面的东西进行数论分块
然后递归计算。
提醒一句:
一定要记忆化,一定要记忆化,一定要记忆化

回到栗子

∑ i = 1 n μ ( i ) \sum_{i=1}^n\mu(i) i=1nμ(i)
把杜教筛的公式套路式子找过来蛤
g ( 1 ) S ( n ) = ∑ i = 1 n ( g ∗ μ ) ( i ) − ∑ i = 2 n g ( i ) S ( n i ) g(1)S(n)=\sum_{i=1}^n(g*\mu)(i)-\sum_{i=2}^ng(i)S(\frac{n}{i}) g(1)S(n)=i=1n(gμ)(i)i=2ng(i)S(in)
看到了 μ \mu μ想一个积性函数,让他们的狄利克雷卷积前缀和很好算
我们知道
∑ d ∣ i μ ( d ) = [ d = 1 ] = e \sum_{d|i}\mu(d)=[d=1]=e diμ(d)=[d=1]=e
也就是说
( 1 ∗ μ ) = e (1*\mu)=e (1μ)=e
e e e的前缀和是啥?
当然是 1 1 1
所以,取 g ( x ) = 1 g(x)=1 g(x)=1
S ( n ) = 1 − ∑ i = 2 n S ( n i ) S(n)=1-\sum_{i=2}^nS(\frac{n}{i}) S(n)=1i=2nS(in)
这样子的话,首先线性筛出一部分的 μ \mu μ的前缀和
然后来一波记忆化搜索美滋滋


再来个栗子把
把上面的 μ \mu μ换成 φ \varphi φ
我们还是知道
∑ d ∣ i φ ( d ) = i = i d ( i ) \sum_{d|i}\varphi(d)=i=id(i) diφ(d)=i=id(i)
所以,如果是 φ \varphi φ的话
就令 g ( x ) = 1 g(x)=1 g(x)=1
所以,
S ( n ) = n ∗ ( n + 1 ) 2 − ∑ i = 2 n S ( n i ) S(n)=\frac{n*(n+1)}{2}-\sum_{i=2}^nS(\frac{n}{i}) S(n)=2n(n+1)i=2nS(in)

多好的套路

但是,不要被套路给套死啦
面对不同的函数
一定要考虑清楚 g g g是啥
好的 g g g能让你的程序更加好算

Part4我也不知道为什么要加上这一部分

好啦
上面好好地写了一下莫比乌斯反演和杜教筛
是不是觉得很简单

当然,莫比乌斯反演和杜教筛当然可以混在一起

莫比乌斯反演推柿子
杜教筛求前缀和
一点也不矛盾


既然我也不知道最后这部分干啥
那就找一堆题目来吧
欢迎查我水表
算了
还是把水表给你们把
莫比乌斯反演的水表
杜教筛的水表


最后,说几句话
不要因为有了杜教筛和线性筛
就天天想着怎么筛
筛不了就滚去写暴力
埃氏筛法很不错
暴力枚举因数也很不错

最后,一句最经典的话作为结尾

骗分过样例,暴力出奇迹

评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值