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