版权声明:本文为博主原创文章,未经博主允许可以转载,但要注明出处 https://blog.csdn.net/wang3312362136/article/details/81537164
莫比乌斯函数和莫比乌斯反演
前置技能
基础数论内容。
莫比乌斯函数
μ(n)
就是莫比乌斯函数,如果有:
n=∏i=1mpaixi(ai>0)
那么:
μ(n)=⎧⎩⎨⎪⎪1(−1)m0n=1∀ai≤1other
莫比乌斯函数有一个很重要的性质,那就是
∑d|nμ(d)=[n=1]
证明:
n=1
时显然。
n=2
时考虑有一个
ai>1
时显然对答案没有影响,那么答案就是
∑ni=0(−1)i(nk)
,这个显然等于
0
。
莫比乌斯反演
若有
f(x)=∑d|xg(d)
则
g(x)=∑d|xf(d)μ(xd)
然而不知道有啥用……
例题
BZOJ 2301
其实就是求
∑i=ab∑j=cd[gcd(i,j)=k]
二维差分一下,这个就等价于求
∑i=1n∑j=1m[gcd(i,j)=k]∑i=1⌊n/k⌋∑j=1⌊m/k⌋[gcd(i,j)=1]
由
∑ni=1μ(n)=[n=1]
得
∑i=1⌊n/k⌋∑j=1⌊m/k⌋∑d|i,d|jμ(d)
优先枚举
d
∑d=1⌊n/k⌋μ(d)∑i=1⌊n/dk⌋∑j=1⌊n/dk⌋1
发现后面的一部分其实就是
⌊ndk⌋⌊mdk⌋
,因此式子就变成了
∑d=1⌊n/k⌋μ(d)⌊ndk⌋⌊mdk⌋
发现最后面的取值只有
O(n‾√)
种,因此可以数论分块得到单次
O(n‾√)
BZOJ 4407
求
∑i=1n∑j=1mgcd(i,j)k
枚举
gcd(i,j)
∑d=1ndk∑i=1n∑j=1m[gcd(i,j)=d]∑d=1ndk∑i=1⌊n/d⌋∑j=1⌊m/d⌋[gcd(i,j)=1]
发现后面是不是很熟悉?再一次用到那个神奇的公式
∑d=1ndk∑i=1⌊n/d⌋∑j=1⌊m/d⌋∑x|i,x|jμ(x)
将
x
提前
∑d=1ndk∑x=1⌊n/d⌋μ(x)∑i=1⌊n/dx⌋∑j=1⌊m/dx⌋1∑d=1ndk∑x=1⌊n/d⌋μ(x)⌊ndx⌋⌊mdx⌋
设
f(d)=dk∑⌊n/d⌋x=1μ(x)
,则
∑d=1nf(d)⌊ndx⌋⌊mdx⌋
显然
f(d)
是一个积性函数,那么我们先线筛出
f(d)
,对
f(d)
做前缀和,就可以做到单次
O(n‾√)
的复杂度了。
杜教筛
前置技能
莫比乌斯反演?
杜教筛
一个积性函数
f(x)
,怎么求前缀和
S(x)=∑xi=1f(x)
?
我们找一个积性函数
g(x)
(不知道它是啥),将它与
f(x)
做一遍卷积:
(f∗g)(n)=∑d|nf(d)g(nd)
将卷积做一遍前缀和:
∑i=1n(f∗g)(i)=∑i=1n∑d|if(d)g(id)=∑i=1n∑d|ig(d)f(id)
后面的部分可以变成
∑d=1ng(d)∑i=1⌊n/d⌋f(i)∑d=1ng(d)S(⌊nd⌋)
因此
∑i=1n(f∗g)(i)=∑d=1ng(d)S(nd)
移项
g(1)S(n)=∑i=1n(f∗g)(i)−∑d=2ng(d)S(nd)
观察到等式右边第一项就是
f∗g
的前缀和,第二项中
S(nd)
的取值最多只有
O(n‾√)
种。
所以,如果
f∗g
很好求,
g
的前缀和很好求,那么我们就可以很快的递归求出
S(n)
的值。
一般是打表算出前几项,然后递归算,注意一定要记忆化(hash/map均可)。
莫比乌斯函数的前缀和?
由于
∑d|nμ(d)=[n=1]
因此我们取
g(x)=1
,直接代入式子:
S(n)=1−∑d=2nS(nd)
欧拉函数?
由于
∑d|nφ(d)=n
因此取
g(x)=1
:
S(n)=n×(n+1)2−∑d=2nS(nd)
总结
这些题大概都有套路?推式子的方法感觉都差不多……