莫比乌斯函数入门

莫比乌斯函数入门

之前遇到过很多次莫反的题,但是每次做完就忘了,云里雾里,所以写一篇来好好记忆一下,下次再忘了就回来看看。
内容和OIWIKI有很大部分的重叠,但是更偏向结论和做法,同时舍弃了一些看不懂的,大多数为别人的复述。

莫比乌斯函数定义:

μ(n)={1n=10n()(1)kkn

性质

μ(n)是积性函数

积性函数

f(ab)f(ab)=f(a)×f(b)ab(ab)

性质

d|nμ(d)={1n=10n1

n所有的因子的函数和的性质

证明

n=i=1ikpicin=i=1ikpi

d|nμ(d)=d|nμ(d)

解释
容易发现n的所有dn是都有的,发现

di=piPpi

证明,若

di×pl=piPpi×pl

pl出现在P之中,则μ(di×Pl)=0
pl不出现在P之中,μ(di×Pl)会在其它情况中被枚举
所以第一个式子是成立的,再者

d|nμ(d)=i=0kCki(1)i

根据二项式定理

(a+b)n=i=0nCniaibni

为上面的式子添加一个b=1

i=0kCki(1)i=(1+(1))k=0

d|nμ(d)={1n=10n1

利用

因为μ是积性函数,所以可以线性筛

void getMu() {
  mu[1] = 1;//初始化
  for (int i = 2; i <= n; ++i) {
    if (!flg[i]) p[++tot] = i, mu[i] = -1;//质数的情况
    for (int j = 1; j <= tot && i * p[j] <= n; ++j) {
      flg[i * p[j]] = 1;
      if (i % p[j] == 0) {
        mu[i * p[j]] = 0;
        break;
      }
      mu[i * p[j]] = -mu[i];//多一个质因数
    }
  }
}

补充结论

[gcd(i,j)=1]=d|gcd(i,j)μ(d)

人话翻译:左边成立,右边为1,反之为0
证明:略

φ(x)=d|xdμ(nd)

莫比乌斯反演

f(x)=d|xg(d)g(x)=d|xμ(xd)f(d)

f(x)=d|xg(d)g(x)=d|xμ(d)f(xd)

这两条就是莫比乌斯反演的结论。

例题

P2522 [HAOI2011] Problem b

原问题相当于询问一个矩阵,用类似于二维前缀和的方式将其拆开,每一部分都是形如:

i=1inj=1jm[gcd(i,j)==k]

的样子,可以化简为:

i=1inkj=1jmk[gcd(i,j)==1]

由之前的结论可得:

i=1inkj=1jnkd|gcd(i,j)μ(d)

我们枚举 d,再枚举 d 的倍数 ,可得:

d=1μ(d)i=1ink[d|i]j=1jnk[d|j]

后面两部分都可以快速的算出,再得:

d=1μ(d)nkdmkd

容易发现现在已经可以 O(n) 解决单次问题了,但是由多组询问,我们预处理 μ 前缀和并使用数论分块优化。 code

SP5971 LCMSUM - LCM Sum

推狮子。

i=1inlcm(i,n)=i=1iningcd(i,n)

n 提出来。

ni=1inigcd(i,n)

枚举 igcd(i,n) 可得。

nd|ni=1inid[gcd(i,n)==d]

像上面一道题一样。

nd|ni=1indi[gcd(i,nd)==1]

经典结论再得:

nd|ni=1indd|gcd(i,nd)μ(d)i

和上面一样。

nd|ni=1indd|gcd(i,nd)μ(d)i

枚举 d 得:

nd|nd|ndμ(d)di=1nddi

S(n)=n(n+1)2

nd|nd|ndS(ndd)μ(d)d

dd=M

nd|nd|ndS(nM)μ(d)d

枚举 M

nM|nS(nM)d|Mμ(d)d

筛出后面这一坨东西,可以一次一次地分开筛。code

杜教筛

一个能在 O(n23) 内求出积性函数前缀和的筛子。

定义

ϵ(n):元函数,返回 [n==1]
I(n):恒等函数,返回值为 1
id(n):单位函数,返回值为 n

狄利克雷卷积

定义两个数论函数 fg 的狄利克雷卷积为 (fg)(n)=d|nf(d)g(nd)
这个东西满足结合律,交换律。

实际上莫比乌斯繁反演就是 μI=ϵ
还有式子,μid=ϕϕI=id

流程

假设我们有一个积性函数 f(n),若我们能够快速得到另一个积性函数 g(n) 前缀和,和他们的狄利克雷卷积 (fg)(n) 前缀和。
这样我们就能够通过杜教筛快速得到 f(n) 的前缀和。
我们知道:

i=1in(fg)(i)=d|if(d)g(id)

并枚举 g(n),则有:

d=1dng(d)i=1indf(i)

i=1nf(i)S(n),表示前缀和,则改为:

d=1dng(d)S(nd)

同时有:

g(1)S(n)=i=1ing(i)S(ni)i=2ing(i)S(ni)

也就是说:

S(n)=i=1in(fg)(n)i=2ing(i)S(ni)g(1)

然后我们对后面的 S(ni) 进行整除分块,并且递归求解。
通过 unordered_map 记忆化和提前筛出前 n23S(i),可以做到 O(n23) 回答前缀和。

μ(n)

我们知道 μI=ϵ,则有

int gmu(int x)
{
    if(x < V-5) return smu[x] ;//提前筛除mu的前缀和
    if(Smu.find(x) != Smu.end()) return Smu[x] ;//记忆化
    int res = 1 ;//前缀和为 1
    for(int le = 2,ri ; le <= x ; le = ri+1)
        ri = min(x,x/(x/le)),res -= (ri-le+1)*gmu(x/le) ; return Smu[x] = res ;
}
ϕ(n)

我们知道 ϕI=id
代码差不多,就是算 (fg)(n) 的方法有点不一样。

int gphi(int x)
{
    if(x < V-5) return sphi[x] ;
    if(Sphi.find(x) != Sphi.end()) return Sphi[x] ; int res = (x+1)*x/2ll ;
    for(int le = 2,ri ; le <= x ; le = ri+1)
        ri = min(x,x/(x/le)),res -= (ri-le+1)*gphi(x/le) ; return Sphi[x] = res ;
}

ϕ(n)n2 Δ

先推一下式子:

i=1inj=1jnijgcd(i,j)

gcd 不太好看,化成 ϕ 的形式。

i=1inj=1jnijd|gcd(i,j)ϕ(d)

所以枚举 d,则有:

d=1dnϕ(d)d2i=1indj=1indij

我们会发现后面两个循环是有通项公式的,记为 S(n),也就是说我们要求的是:

d=1dnϕ(d)d2S(nd)

显然可以对 S(n) 进行整除分块,考虑如何求出 ϕ(i)i2 的前缀和。
注意到这比普通的 ϕ(i) 多出了一个 i2,所以将 g 函数构造为 id2,所以在狄利克雷卷积时有:

(fg)(n)=d|nϕ(d)d2(nd)2=n2d|nϕ(d)=n3

显然这个 (fg)(n) 也有通项公式,然后这题就做完了。
需要注意的是即使外面有一层整除分块,但时间仍然为 O(n23)

...

后面有时间了再更,就当入个门

本文作者:谭皓猿

本文链接:https://www.cnblogs.com/snow-panther/p/17527007.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   谭皓猿  阅读(43)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起