Live2D

Note -「Mobius 反演」光速入门

  UPD:修改了 Euler 筛法代码框架。

  若无特别说明,x,y 等形式变量均 N+p 为素数。

Preface

数论函数

  我们称任意 f:N+C 为一个数论函数。

积性函数

  对于两个数论函数 f,若对于任意 xy(即 x,y 互素,或说 gcd(x,y)=1),都有 f(x)f(y)=f(xy),那么称此数论函数是积性函数,且显然有 f(1)=1

  可以发现,在此定义下,我们只需要知道该函数在素数幂(pc (cN+))处的点值,就能还原整个函数。

  特别地,若任意 x,y 都有 f(x)f(y)=f(xy),那么称此数论函数是完全积性函数。例如,I(n)=1 是一个常函数,自然可以得到它是一个完全积性函数。

  重要的一点是,绝大部分积性函数可以在 Euler 筛法的框架下快速求出所有点值。

  积性在一些函数运算中得以延续。设 f,g 为积性函数,kN+,则:

  • h(n)=(f(n))k 积性(不写作 fk(n) 是为区别 Dirichlet 卷积);
  • h(n)=f(nk) 积性;
  • h(n)=f(n)g(n) 积性;
  • h(n)=(fg)(n) 积性,后文详解。

Dirichlet 卷积

  卷积是什么呢?对于任意三个函数 f,g,h,若有:

h(k)=ij=kf(i)g(j)

  则 hfg 卷积。例如 为加号,则 hfg 的普通卷积;若 为异或,则 hfg 的异或卷积。

  而当 为乘号,f,g,h 为数论函数,有

h(k)=ij=kf(i)g(j)

  此时 h 即为 fg Dirichlet 卷积的结果。记为

h=fg

  当然,另一种表达方式为

h(k)=i|nf(i)g(ki)

  Dirichlet 卷积有以下性质:

  • 交换律:fg=gf
  • 结合律:(fg)h=f(gh)
  • 分配律:f(g+h)=fg+fh

  带入可证,此处略过。

  Dirichlet 卷积还有一个重要性质:f,g 积性,则 h=fg 积性

  证明:对于任意 xy

h(x)h(y)=(dx|xf(dx)g(xdx))(dy|yf(dy)g(ydy))=dx|xdy|yf(dx)f(dy)g(xdx)g(ydy)=dx|xdy|yf(dxdy)g(xydxdy)=d|xyf(d)g(xyd)=h(xy)

Dirichlet 卷积中的特殊函数

  Dirichlet 卷积既然已是一种函数间的运算,我们就有必要研究一些特殊的“运算值”。例如零元,幺元等。一些常用的函数如下:

  • I(n)=1,常数函数;
  • ϵ(n)=[n=1],单位函数,Dirichlet 卷积的(左、右)幺元;
  • id(n)=n,恒等函数。

  这三者看似无用,但它们之间的运算可以表达出常见的数论函数:

  • φ(n),欧拉函数;

  • σ0(n),约数个数函数;

  • ……

  突然,Mobius 就提出一个问题:I 在 Dirichlet 卷积下的逆元是什么?

Mobius 函数 & Mobius 反演

Mobius 函数 μ

  逆元?两数相乘为 1 是乘法逆元,类似地,两函数相卷得到幺元 ϵ,则两函数互为卷积逆元。Mobius 函数实际上就是一个构造出的 I 的逆元,记作 μ

  μ 是一个积性函数,定义式为:

μ(n)={1n=1(1)kn=p1p2pk,    p 为两两不同的素数0otherwise

  这样看着很臃肿。注意 μ 是一个积性函数,我们只需要描述起在 pc (cN+) 处的点值。可以看出:

μ(pc)=[c=1](1)

  μ 函数是为了满足下式:

Iμ=ϵ

  即:

d|nμ(d)=[n=1]

  证明n=1 时显然成立,仅需证明 n>1 时左式恒为 0。设 n=piαi,显然仅需考虑左式中 d=pi 时的和。不妨设 n 含有素因子的集合为 P,则左式有:

d|nμ(d)=SPμ(pSp)=SP(1)|S|=|S|[0,|P|](|P||S|)(1)|S|=(11)|P|=0|P|    (|P|>0)=0

  在此后的推导中,我们通常仅把 μ 看做“I 的逆元”而不考虑其内部表达式,故多数情况不需要如此考虑其展开后的运算。

Mobius 反演

  充分认识 μ 之后,反演公式其实非常浅显。对于两个数论函数 f,g,满足:

f=gIg=fμ

  证明:左式左右同时卷 μ 即证 ;右式左右同时卷 I 即证

  还有两种和式形式:

(1)f(n)=d|ng(d)g(n)=d|nf(d)μ(nd)

(2)f(n)=n|dg(d)g(n)=n|df(d)μ(dn)

  (1) 即为卷积形式,已证,下证 (2)

  证明,仅证 ,倒推结论:

n|df(d)μ(dn)=k=1+f(kn)μ(k)=k=1+μ(k)kn|df(d)=n|dg(d)k|ndμ(k)=n|dg(d)ϵ(nd)=g(n)

基础应用

  我们来推导几个常见的函数或式子。

约数个数 σ0

  定义式:σ0(n)=d|n1

σ0(n)=d|n1=d|nI(d)I(nd)=I2(n)

  结论:

σ0=I2

欧拉函数 φ

  定义式:φ(n)=i=1n[in]

φ(n)=i=1n[in]=i=1nd|id|nμ(d)    =d|nμ(d)nd=d|nμ(d)id(nd)=(μid)(n)

  标注  的步骤运用了 Mobius 反演,下文亦如此。结论:

φ=μid

反演魔法

例一

  类似题目 Link.

  给定 n,m,k,求

i=1nj=1m[gcd(i,j)=k]

  传说中的七倍经验题。直接来叭:

i=1nj=1m[gcd(i,j)=k]=i=1nkj=1mk[ij]=i=1nkj=1mkd|id|jμ(d)    =d=1min{nk,mk}μ(d)nkdmkd

  O(n) 预处理后整除分块即可 O(n) 求解。整除分块是莫反题中高频出现的 trick,一定要用熟。

例二

  BZOJ 2693.

  给定 Tn,m,对于每组,求

i=1nj=1mlcm(i,j)mod(108+9)

  T104n,m107

  式子很简单,主要运用换元法

i=1nj=1mlcm(i,j)=d=1ndi=1ndi=1mdij[ij]=d=1ndd=1ndS(ndd)S(mdd)d2    let S(n)=n(n+1)2=T=1nS(nT)S(mT)Td|Tdμ(d)    let T=dd    

  再令 f(n)=nd|ndμ(d),由于化简不来,我们转而证明它积性可直接筛,具体可见下文「线性筛 trick」。

  最终 O(n)O(n) 解决。

例三

  51nod 1584.

  令 σ(n)n 的约数之和。给出 Tn,对于每个 n,求

i=1nj=1nmax{i,j}σ(ij)mod(109+7)

  T5×104n106

  只要睡醒了应该是有把 max 拆开的意识的。原式化为

2i=1nij=1iσ(ij)i=1niσ(i2)

  σ(i2) 可证积性,直接筛出后一项。对于前一项,我们先来研究 σ(ij) 的性质:

  引理

σ(ij)=x|iy|jxy[xjy]

  证明:对于每个 d|ij,当且仅当 y=gcd(d,j), x=dy 时被统计一次。考虑一个 a|da|ia|j,一定有 a|x,不然就不可能有 xjy,所以以上表述成立。

  利用引理,记 f(n)=ni=1nσ(ni),推导:

f(n)=ni=1nx|ny|ixy[xiy]=ni=1nx|ny|ixyd|xd|iyμ(d)    =ni=1nd|nd|iμ(d)x|nd|xy|id|yixy=ni=1nd|nd|iμ(d)x|ndy|idixy,    x,y 同时约掉 d=ni=1nd|nd|iμ(d)σ(nd)y|idiy=ni=1nd|nd|iμ(d)σ(nd)dy|idiyd=ni=1nd|nd|idμ(d)σ(nd)σ(id)=nd|ndμ(d)σ(nd)i=1ndσ(i)

  筛出 μ,σ,枚举 dnd,可以 O(nlnn) 算出所有 f,具体可见下文「O(nlnn) 刷表 trick」以及我的题解

  最终,O(nlnn)O(1) 解决问题。

魔法中的 tricks

  毕竟 Mobius 反演不能把所有式子化成一眼能求。当我们在推导过程中卡住的时候,可以尝试用一些 trick “暴力”计算得到的式子,说不定就是正解呢!

线性筛 trick

  记住一句话:积性函数都能筛

  Euler 筛法的框架如下:

inline void sieve ( const int n ) {
      /* 初始化函数在 1 处的点值(=1) */
      for ( int i = 2; i <= n; ++i ) {
            if ( !vis[i] ) {
                  pr[++pn] = i];
                  /* 计算函数在素数处的点值 */
            }
            for ( int j = 1, t; ( t = i * pr[j] ) <= n; ++j ) {
                  vis[t] = true;
                  /* 注意:pr[j] 一定是 t 的最小素因子 */
                  if ( i % pr[j] ) {
                        /* pr[j] \not| i,利用积性处理 t 处点值 */
                  } else {
                        /* pr[j] | i,特殊处理 t 处点值 */
                        break;
                  }
            }
      }
}

  难点只有两个:

  • 如何判断某个函数是积性函数?
  • 如何处理计算的 t 处点值?

  对于前者,打表(迫真)和带入计算都是不错的选择。后者则需要根据函数表达式灵活处理,一般来说都是加减乘除能够解决的,某些情况(例如筛 σ1)需要额外记录信息。

σ1

  σ1 也简记作 σ,有定义

σ(n)=d|nd

  则任意一对 xy,带入

σ(x)σ(y)=dx|xdxdy|ydy=dx|x,dy|ydxdy=d|xyd=σ(xy)

  第三步用了 xy 的条件。可见 σ 积性,考虑如何筛。

  小奥教会我们,对于 n=piαi(标准分解形式),有

σ(n)=j=0αipij

  证略。我们来处理筛法中的特殊情况,设 p=pkx 的最小素因子,则应有 p2|x。观察:

σ(xp)=(pipj=0αipij)(j=0αkpj)σ(x)=(pipj=0αipij)(j=0αk+1pj)

  乘积式很难直接修改某一项的值,所以我们需要对于每个 x,记录其最小素因子的贡献,记作 σp(x),有

σp(x)=j=0αkpj

  σp 很显然可以在筛法中处理。此后,就能得到

σ(x)=σ(xp)σp(xp)σp(x)

  问题解决。值得再次强调的是,Euler 筛法中的合数一定被其最小素因子筛掉

idkμ

  即 洛谷 P4449 的阶段性问题。

  做题的时候,经常遇见此类很多个基础的积性函数卷起来的函数,它们亦可被线性筛。

  同样的姿势,设 px 的最小素因子,且有 p2|x,观察:

idkμ(xp)=d|xpdkμ(xdp)idkμ(x)=d|xdkμ(xd)

  分类讨论第二个和式中的 d

  1. 不含新加入的素因子 p,对应了第一个和式中的每个 dkμ(xdp),只不过 x 多了一个 p,所以应为 dkμ(xd)。由于 p2|x,且 d|xpp|xd,故 μ(x)=μ(xd)=0,无贡献;
  2. 含有新加入的素因子 p,亦对应第一个和式中的每个 dkμ(xdp),只不过 d 多了一个 p,所以应为 dkpkμ(xdp)

  综上:

idkμ(x)=pk(idkμ)(xp)

f(n)=nd|ndμ(d)

  这是上文的问题,我们得证明它能筛(积性),在得出它如何筛。

  还是惯用手法,带入任意 xy

f(x)f(y)=(xdx|xdxμ(dx))(ydy|ydyμ(dy))=xydx|x,dy|ydxdyμ(dx)μ(dy)=xyd|xydμ(d)=f(xy)

  果然积性。

  当然,也可以用积性的延续性质。发现

f=((μid)I)id

  亦能说明 f 积性。

  接下来,我们从积性的角度着手,思考素数幂 pk 处的点值。边界有:

f(p)=p(1p)

  对于其他 k>1

f(pk)=pki=0kpiμ(pi)=pk(1p)=pf(pk1)

  所以在筛法中,有 p2|x,那么:

f(x)=pf(xp)

  简洁地结束问题。

O(nlnn) 刷表 trick

  基于 i=1nni=O(nlnn),很多时候可以把 Dirichlet 卷积形式的函数暴力打表出来。框架如下:

for ( int i = 1; i <= MAXN; ++i ) {
    for ( int j = 1, t; ( t = i * j ) <= MAXN; ++j ) {
        /* 用 i 和 j 的信息对 t=i*j 贡献 */
    }
}

  以前文求

f(n)=nd|ndμ(d)σ(nd)i=1ndσ(i)

  为例,步骤如下:

  1. 常系数剔除:n 显然最后再乘上去。

  2. 形式变化:类似变化乘法卷积的操作,把式子变化成形如 d|nA(d)B(nd) 的形式。此处有

    f(n)n=d|n(dμ(d))(σ(nd)i=1ndσ(i))

  3. 预处理上述 A(n)B(n) 的值。此处即筛出 μσ,预处理 σ 前缀和。

  4. 套用框架计算。

  莫得什么难点。(

Conclusion

  莫反题的难点一般不是莫反。(

  Practice makes perfect. 式子多推一下自然能找到感觉。建议尝试自己推导文中的式子,再对照文中的推导看看是否可以优化。(当然我可能推得很细,也可能兔子就是要蠢一点 qwq。

  更多莫反题可在 OI-Wiki 以及 我的博客 中挑选嗷~

  终于写完了 qwq!

posted @   Rainybunny  阅读(382)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示