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

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我也不知道为什么要加上这一部分

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

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

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


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


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

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

骗分过样例,暴力出奇迹

  • 23
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 13
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值