莫比乌斯反演与杜教筛文章(转)

链接:https://blog.csdn.net/qq_30974369/article/details/79087445

Part0

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

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

Part1莫比乌斯反演

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

基本的公式


对于一个函数f(x)f(x)
设g(x)=∑x|df(d)g(x)=∑x|df(d)
那么

f(x)=∑x|dμ(dx)g(d)f(x)=∑x|dμ(dx)g(d)


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

随手搞道题目来说吧


∑i=1n∑j=1m[gcd(i,j)=1]∑i=1n∑j=1m[gcd(i,j)=1]

这个东西很直接,
所以我们设

f(x)=∑i=1n∑j=1m[gcd(i,j)=x]f(x)=∑i=1n∑j=1m[gcd(i,j)=x]

g(x)=∑x|df(d)g(x)=∑x|df(d)


根据莫比乌斯反演可以得到

f(1)=∑1|dμ(d1)g(d)=∑i=1nμ(i)g(i)f(1)=∑1|dμ(d1)g(d)=∑i=1nμ(i)g(i)


g(x)g(x) 是什么东西?

g(x)=∑i=1n∑j=1m[x|gcd(i,j)]g(x)=∑i=1n∑j=1m[x|gcd(i,j)]


直接把xx 除到上面去

g(x)=∑i=1n/x∑j=1m/x[1|gcd(i,j)]g(x)=∑i=1n/x∑j=1m/x[1|gcd(i,j)]


[1|gcd][1|gcd] 显然成立的
所以g(x)=[nx][mx]g(x)=[nx][mx]
可以O(1)O(1) 计算
所以,f(1)f(1) 可以O(n)O(n) 计算


一起推下式子

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

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

这两题按照顺序看嗷

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

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

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


∑i=1n∑j=1mgcd(i,j)∑i=1n∑j=1mgcd(i,j)

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

所以,我们枚举gcdgcd 的值

∑d=1nd∑i=1n∑j=1m[gcd(i,j)=d]∑d=1nd∑i=1n∑j=1m[gcd(i,j)=d]


后面的那一部分是不是想到了前面推出的东西???
所以先把dd 直接除上去

∑d=1nd∑i=1n/d∑j=1m/d[gcd(i,j)=1]∑d=1nd∑i=1n/d∑j=1m/d[gcd(i,j)=1]


n/dn/d 和m/dm/d 不要想太多,你就当成xx 和yy

∑i=1x∑j=1y[gcd(i,j)=1]∑i=1x∑j=1y[gcd(i,j)=1]


不就是上面推过的第一个例子??

=∑i=1xμ(i)[xi][yi]=∑i=1xμ(i)[xi][yi]

把这一截放回我们要求的式子里面去

∑d=1nd∑i=1xμ(i)[xi][yi]∑d=1nd∑i=1xμ(i)[xi][yi]


把x,yx,y 还是写成原样吧

∑d=1nd∑i=1n/dμ(i)[nid][mid]∑d=1nd∑i=1n/dμ(i)[nid][mid]

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

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

那我们就继续推一步
我们是不是可以直接对nidnid 分块呢?
所以,我们设T=idT=id 把idid 换一下

∑d=1nd∑i=1n/dμ(i)[nT][mT]∑d=1nd∑i=1n/dμ(i)[nT][mT]


这个时候,比较关键的一步
把TT 提出来

∑T=1n[nT][mT]∑d|Tdμ(Td)∑T=1n[nT][mT]∑d|Tdμ(Td)


为什么是这个??
我们来分析一波
首先每一个TT 一定对应[nT][mT][nT][mT]
这一项之和TT 有关,所以可以提出来

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

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

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

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


其实,如果我们继续观察,很容易知道一点:
∑d|Tdμ(Td)=φ(T)∑d|Tdμ(Td)=φ(T)

证明?直接从狄利克雷卷积的角度来吧
我们知道(1∗φ)(i)=i(1∗φ)(i)=i
还知道(1∗μ)(i)=e(1∗μ)(i)=e
其中11 是f(x)=1f(x)=1
ee 是f(x)=[x=1]f(x)=[x=1]
idid 是f(x)=xf(x)=x
我们的式子等于
(id∗φ)(i)=(φ∗1∗μ)(i)=(φ∗(1∗μ))(i)=(φ∗e)(i)=φ(i)(id∗φ)(i)=(φ∗1∗μ)(i)=(φ∗(1∗μ))(i)=(φ∗e)(i)=φ(i)

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


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

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

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

Part2线性筛

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

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

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

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

μμ 莫比乌斯函数

这个怎么筛应该都会吧

φφ 欧拉函数

怎么筛应该也很明显吧。

dd 约数个数

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

σσ 约数和

还是唯一分解定理
x=∏paiix=∏piai
σ(x)=∏(∑aij=0pji)σ(x)=∏(∑j=0aipij)
记录一下最小质因子的上面那个式子的和
以及这个因子的aiai 次幂
每次也是先除掉再乘上新的

akak kk 次幂

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

invinv 乘法逆元

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


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

Part3杜教筛

来个栗子

线性筛O(n)O(n) 复杂度,美滋滋
好的,我知道了
来一个很interestinginteresting 的题目???

求∑i=1nμ(i)的值求∑i=1nμ(i)的值

我当然知道你会线性筛
所以n<=109n<=109

杜教筛是蛤?

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

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

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

我再来找个积性函数g(i)g(i) (不知道是啥)
让gg 和ff 做一个卷积

(g∗f)(i)=∑d|ig(d)f(id)(g∗f)(i)=∑d|ig(d)f(id)


再求一下卷积的前缀和

∑i=1n(g∗f)(i)=∑i=1n∑d|ig(d)f(id)∑i=1n(g∗f)(i)=∑i=1n∑d|ig(d)f(id)


把dd 给提出来

∑d=1ng(d)∑d|if(id)∑d=1ng(d)∑d|if(id)

∑d=1ng(d)∑i=1n/df(i)∑d=1ng(d)∑i=1n/df(i)

∑d=1ng(d)S(nd)∑d=1ng(d)S(nd)


如果仔细想想
我们就会有这个式子:

g(1)S(n)=∑i=1ng(i)S(ni)−∑i=2ng(i)S(ni)g(1)S(n)=∑i=1ng(i)S(ni)−∑i=2ng(i)S(ni)


前面的东西是狄利克雷卷积

g(1)S(n)=∑i=1n(g∗f)(i)−∑i=2ng(i)S(ni)g(1)S(n)=∑i=1n(g∗f)(i)−∑i=2ng(i)S(ni)


如果狄利克雷卷积的前缀和非常好算的话
那么我们就可以对后面的东西进行数论分块
然后递归计算。
提醒一句:
一定要记忆化,一定要记忆化,一定要记忆化

回到栗子

∑ni=1μ(i)∑i=1nμ(i)
把杜教筛的公式套路式子找过来蛤

g(1)S(n)=∑i=1n(g∗μ)(i)−∑i=2ng(i)S(ni)g(1)S(n)=∑i=1n(g∗μ)(i)−∑i=2ng(i)S(ni)


看到了μμ 想一个积性函数,让他们的狄利克雷卷积前缀和很好算
我们知道

∑d|iμ(d)=[d=1]=e∑d|iμ(d)=[d=1]=e


也就是说

(1∗μ)=e(1∗μ)=e


ee 的前缀和是啥?
当然是11 了
所以,取g(x)=1g(x)=1

S(n)=1−∑i=2nS(ni)S(n)=1−∑i=2nS(ni)


这样子的话,首先线性筛出一部分的μμ 的前缀和
然后来一波记忆化搜索美滋滋


再来个栗子把
把上面的μμ 换成φφ
我们还是知道

∑d|iφ(d)=i=id(i)∑d|iφ(d)=i=id(i)


所以,如果是φφ 的话
就令g(x)=id(x)=xg(x)=id(x)=x
所以,

S(n)=n∗(n+1)2−∑i=2niS(ni)S(n)=n∗(n+1)2−∑i=2niS(ni)

多好的套路

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

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

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

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

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


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


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

猜你喜欢

转载自blog.csdn.net/qq_37451344/article/details/82556006