【算法】莫比乌斯反演

参考博客

OI-Wiki | Biuld-数学 | Million-组合计数学习笔记 | 狄利克雷卷积和莫比乌斯反演 | 算法学习笔记(35): 狄利克雷卷积

狄利克雷卷积

莫反的前置知识,主要引入了一个新运算。

常用积性函数

  1. 单位函数
    ε(n)={1n=10otherwise
  2. 幂函数
    Idk(n)={nknk=11k=0

k=1 时,Idk(n) 也等价于恒等函数 Id(n);当 k=0 时,Idk(n) 等价于常数函数 1(n)

注意这里的恒等函数和常数函数读者虽感觉没什么用,显然可以不用函数表达,但是请注意只有数论函数才能进行下面将要提到的狄利克雷卷积运算,所以这两个函数式必不可少的。并且这里的 1(n) 中的 1 不是 1,而是加粗后的 1,代表常数函数,请注意区分。

  1. 除数函数
    σk(n)={d|ndkd|ndk=1d|n1k=0

k=1 时,σk(n) 等价于因数函数 σ(n);当 k=0 时,σk(n) 等价于个数函数 d(n)

  1. 欧拉函数
    φ(n)=i=1npiai1(pi1)=ni=1n(11pi)φ(pk)=pkpk1=(p1)pk1

这里只有欧拉函数的计算式,详情可以自行搜索一下。

定义

狄利克雷卷积是定义在数论函数间的二元运算,可以理解为一种新运算方式,运算符号为

定义式为:

(fg)(n)=d|nf(d)g(nd)

也可表示为:

(fg)(n)=ij=nf(i)g(j)

定理

  1. f,g 都为积性函数,那么 fg 也为积性函数
  2. 交换律:fg=gf
  3. 结合律:(fg)h=f(gh)
  4. 分配律 f(g+h)=fg+fh

特殊函数的卷积

  1. Idk1=σ

(Idk1)(n)=d|ndk×1=σk(n)

  1. φ1=Id

从简单的情况分析,假设 n=pq

(φ1)(n)=d|nφ(d)=φ(1)+i=1qφ(pi)=1+i=1qpipi1=pq=n

考虑普遍情况,分解 n=piqi

(φ1)(n)=(φ1)(piqi)=(φ1)(piqi)=piqi=n=Id

  1. 11=d

(11)(n)=d|n1=d

  1. σ=φd

从前三条可推出本条式子,σ=Id1=φ11=φd

单位元和逆

对于狄利克雷卷积,单位元 τf=f,由此不难得出狄利克雷卷积的单位元为 ε

与此相对的定义式逆,对于狄利克雷卷积,狄利克雷逆 gf=ε,记作 f1。由此显然可得若一个函数 f 存在狄利克雷逆的充要条件是 f(1)0

莫比乌斯反演

莫比乌斯函数

定义莫比乌斯函数 μ=11。普通定义式为 μ(n)={1n=10n存在平方因子1kkn

莫比乌斯反演

由莫比乌斯函数可得,g=f1f=gμ

?感觉铺垫的很长,结束的很潦草?

一个莫比乌斯反演的经典结论是 d|gcd(i,j)μ[d]=[gcd(i,j)=1]。考虑证明这个式子。

由莫比乌斯函数的定义可知,μ1=ε,所以 d|nμ(d)=ε(n)。令 n=gcd(i,j),再将 ε 的定义带进去,便得出了上面的式子。

应用

  1. 经典转化

对于 i=1nj=1ngcd(i,j) 这一类的问题,可以考虑转化为枚举 gcd 值变为 d=1ndi=1nj=1n[gcd(i,j)=d],再令 i=Id,j=Jd,带回去就是 d=1ndId=1nJd=1n[gcd(Id,Jd)=d],同时除以一个 d 并把 I,J 变回 i,j 式子就改写成 d=1ndi=1ndj=1nd[gcd(i,j)=1]

再用上面的结论将它反演成 d=1ndi=1ndj=1ndk|gcd(i,j)μ(k),换一下枚举顺序变为 d=1ndk=1ndμ(k)i=1nd[k|i]j=1nd[k|j]。发现 i=1nd[k|i]=nk,于是式子变为 d=1ndk=1ndμ(k)nkd2

接着我们令 T=kd,枚举 T,式子变为 T=1nnT2d|Tdμ(Td),后面这个东西发现很能预处理,再整除分块一下,然后就可以做到 O(n) 了。

  1. gcd 为质数

跟上面的差不蛮多,只是最后的式子变成 TprimenT2d|Tμ(Td),导致预处理的时候发生一点小变化而已。


3. 序列上的 lcm

和上面那个很像,但用的比较多还是提一下。跟上面一样的就一笔带过了。下面的式子 n 代表序列长度,m 代表值域。

i=1nj=1nlcm(ai,aj)=i=1nj=1naiajgcd(ai,aj)=d=1mi=1nj=1naiajd[gcd(ai,aj)=d]

这个序列上的值看的就很让人难受,开个桶 bi=j=1n[aj=i],就可以继续往下化了

d=1mi=1nj=1naiajd[gcd(ai,aj)=d]=d=1mi=1nj=1nbibj×ijd[gcd(i,j)=d]=d=1mi=1ndj=1ndbidbjd×ijd[gcd(i,j)=1]=d=1mdi=1ndj=1ndbidbjd×ijk|gcd(i,j)μ(k)=d=1mdk=1mdμ(k)i=1ndi[k|i]×bidj=1ndbjd×j[k|j]

这时候发现后面这些带 [k|i] 之类的东西就十分的烦了,因为它代表的是 [1,nd] 中所有 k 的倍数的和,而 k 每次又不一样,即不能整除分块又不能预处理。因此我们考虑令 i=Ik,j=Jk,这样强制满足 i,jk 的倍数,然后再同时除以一个 k。式子可化为

d=1mdk=1mdμ(k)i=1ndi[k|i]×bidj=1ndbjd×j[k|j]=d=1mdk=1mdμ(k)k2i=1ndki×bidkj=1ndkbjdk×j

接着我们令 f(n)=k=1nμ(k)k2i=1nki×bikj=1nkbjk×j,前半关于 k 的部分显然可以直接预处理,后面的发现是相对独立的,直接把它变成 (i=1nki×bik)2,然后可以 log 暴力求。(ps:如果不是在序列中求的话后面这一块东西不会有含 b 次项,可以整除分块)。

原式就变成 d=1mdf(nd),整除分块一下即可。

  1. 约数个数和

即求 i=1ni=1md(ij)d(x) 表示 x 的约数和。这种题要用到一个公式,如下:

d(ij)=x|iy|j[gcd(x,y)=1]

考虑证明这个东西。先从简单的情况入手,令 i=pa,j=pb,那么 ij=pa+bd(ij)=a+b+1,也就是选 0p,选 1p……选 a+bp。而 x|iy|j[gcd(x,y)=1]=a+b+1,也就是在 x 中选 [1,a] 个同时在 y 中不选 p,在 y 中选同时不在 x 中选,x,y 中都不选。 因此等式成立

然后开始正式地推式子:

i=1ni=1md(ij)=i=1ni=1mx|iy|j[gcd(x,y)=1]=x=1ny=1mi=1nj=1m[x|i][y|j][gcd(x,y)=1=x=1ny=1mnxmy[gcd(x,y)=1]=x=1ny=1mnxmyd|gcd(x,y)μ(d)=d=1min(n,m)μ(d)x=1ny=1mnxmy[d|x][d|y]=d=1min(n,m)μ(d)x=1nnxdy=1mmyd

然后整除分块一下,结束。

后面的套路总结等我做多了题再回来总结awa

posted @   Cloote  阅读(41)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下
点击右上角即可分享
微信分享提示