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)=∑x∣df(d)
那么
f
(
x
)
=
∑
x
∣
d
μ
(
d
x
)
g
(
d
)
f(x)=\sum_{x|d}\mu(\frac{d}{x})g(d)
f(x)=x∣d∑μ(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=1∑nj=1∑m[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=1∑nj=1∑m[gcd(i,j)=x]
g
(
x
)
=
∑
x
∣
d
f
(
d
)
g(x)=\sum_{x|d}f(d)
g(x)=x∣d∑f(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)=1∣d∑μ(1d)g(d)=i=1∑nμ(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=1∑nj=1∑m[x∣gcd(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=1∑n/xj=1∑m/x[1∣gcd(i,j)]
[
1
∣
g
c
d
]
[1|gcd]
[1∣gcd]显然成立的
所以
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=1∑nj=1∑mgcd(i,j)
这个肯定没有前面我给的例子的莫比乌斯反演那么直接
但是我们观察一下,
g
c
d
gcd
gcd的取值有哪些??
1
~
n
1~n
1~n(假设
n
<
m
n<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=1∑ndi=1∑nj=1∑m[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=1∑ndi=1∑n/dj=1∑m/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=1∑xj=1∑y[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=1∑xμ(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=1∑ndi=1∑xμ(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=1∑ndi=1∑n/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=1∑ndi=1∑n/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=1∑n[Tn][Tm]d∣T∑dμ(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)
∑d∣Tdμ(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=2∗2∗2∗3∗3
他就会被他的最小质因子给筛到
也就是
2
∗
36
2*36
2∗36时被筛到
所以,一般线性筛如果要存储其他的东西来筛的话
一定是记录最小质因子的东西
大概的写一下几个积性函数:
μ \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=1∑nμ(i)的值
我当然知道你会线性筛
所以
n
<
=
1
0
9
n<=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})
(g∗f)(i)=d∣i∑g(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=1∑n(g∗f)(i)=i=1∑nd∣i∑g(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=1∑ng(d)d∣i∑f(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=1∑ng(d)i=1∑n/df(i)
∑
d
=
1
n
g
(
d
)
S
(
n
d
)
\sum_{d=1}^ng(d)S(\frac{n}{d})
d=1∑ng(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=1∑ng(i)S(in)−i=2∑ng(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=1∑n(g∗f)(i)−i=2∑ng(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=1∑n(g∗μ)(i)−i=2∑ng(i)S(in)
看到了
μ
\mu
μ想一个积性函数,让他们的狄利克雷卷积前缀和很好算
我们知道
∑
d
∣
i
μ
(
d
)
=
[
d
=
1
]
=
e
\sum_{d|i}\mu(d)=[d=1]=e
d∣i∑μ(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)=1−i=2∑nS(in)
这样子的话,首先线性筛出一部分的
μ
\mu
μ的前缀和
然后来一波记忆化搜索美滋滋
再来个栗子把
把上面的
μ
\mu
μ换成
φ
\varphi
φ
我们还是知道
∑
d
∣
i
φ
(
d
)
=
i
=
i
d
(
i
)
\sum_{d|i}\varphi(d)=i=id(i)
d∣i∑φ(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=2∑nS(in)
多好的套路
但是,不要被套路给套死啦
面对不同的函数
一定要考虑清楚
g
g
g是啥
好的
g
g
g能让你的程序更加好算
Part4我也不知道为什么要加上这一部分
好啦
上面好好地写了一下莫比乌斯反演和杜教筛
是不是觉得很简单
当然,莫比乌斯反演和杜教筛当然可以混在一起
莫比乌斯反演推柿子
杜教筛求前缀和
一点也不矛盾
既然我也不知道最后这部分干啥
那就找一堆题目来吧
欢迎查我水表
算了
还是把水表给你们把
莫比乌斯反演的水表
杜教筛的水表
最后,说几句话
不要因为有了杜教筛和线性筛
就天天想着怎么筛
筛不了就滚去写暴力
埃氏筛法很不错
暴力枚举因数也很不错
最后,一句最经典的话作为结尾
骗分过样例,暴力出奇迹