莫比乌斯反演

这里讲述几个莫比乌斯反演的套路技巧。我们从一道道例题讲起。

  • i=1nj=1n[gcd(i,j)=1]=i=1nμ(i)ni2

这就是一般公式 [gcd(i,j)=1]=d|i,d|jnμ(d) 的衍生,不会做不了题。

  • 暴力算 gcd 转换为枚举最大公约数

例题1 P2568 GCD

给定正整数 n,求 1x,yngcd(x,y) 为素数的数对 (x,y) 有多少对。

思路点拨

如果我们暴力的去枚举一个个 x,y ,缓慢的算出 gcd 之后还判断是不是素数,这样会超时。但是我们转念一想,我们可以枚举 gcd 的那么素数

i=1nj=1n[gcd(i,j)Sprime]

=dSprime,dni=1nj=1n[gcd(i,j)=d]

=dSprime,dni=1ndj=1nd[gcd(i,j)=1]

接下来就会有两种做法,欧拉函数或者莫反,这里讲述莫反,就是套上述的套路一。

=dSprime,dni=1ndμ(i)nid2

这样运用富比尼定理就可以 O(nn) 了。但是不可以通过。

  • T=id 并且枚举T

这样往往可以优化时间。

=T=1nnT2dSprime,d|Tμ(Td)

左边富比尼定理,右边筛法算就可以了。

  • 分母分子分开算

  • lcmgcd

有时候我们需要计算的东西是一堆分数的乘积并且取余数,那么就可以这样降低思考难度。

例题二 P5221 Product

i=1Nj=1Nlcm(i,j)gcd(i,j) (mod 104857601)

我们知道,在膜意义下的运算,分母是会被运用欧拉定理转化为幂的形式的,所以有交配律,原式就可以被转化为:

=i=1Nj=1Nlcm(i,j)i=1Nj=1Ngcd(i,j) (mod 104857601)

莫反不好考虑 lcm ,转化为 gcd :

=i=1Nj=1Niji=1Nj=1Ngcd2(i,j) (mod 104857601)

分开考虑,先从简单的分子下手:

i=1Nj=1Nij=i=1NiN(n!)N=(n!)2N

在考虑分母,平方先去掉,最后再一起算。

=i=1Nj=1Ngcd(i,j)

我们按照上边的套路,取枚举 gcd ,原式可以转化为:

=d=1Ndi=1nj=1n[gcd(i,j)=d]

考虑幂次的部分,记得欧拉降幂不然会WA:

i=1nj=1n[gcd(i,j)=d]=i=1ndj=1nd[gcd(i,j)=1]

这个东东欧拉函数算就可以了。但是莫比乌斯函数也不是不行。

最后我们讲一道略难的综合题。

例题三 [SDOI2017]数字表格

题目背景

Doris 刚刚学习了 fibonacci 数列。用 fi 表示数列的第 i 项,那么

f0=0,f1=1

fn=fn1+fn2,n2

题目描述

Doris 用老师的超级计算机生成了一个 n×m 的表格,

i 行第 j 列的格子中的数是 fgcd(i,j),其中 gcd(i,j) 表示 i,j 的最大公约数。

Doris 的表格中共有 n×m 个数,她想知道这些数的乘积是多少。

答案对 109+7 取模。

思路点拨

我们知道,斐波拉契数列这东西一下求这么多和并不好算,但是因为 n,m106 ,所以最多只会有 106 个数被访问,我们直接想到枚举下标。

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

  • 套路把 d 给提出来(之前都用了很多遍了)

d=1nfdi=1ndj=1md[gcd(i,j)=1]

注意,这里是体现莫比乌斯函数优越性的地方了,应为 n,m 不相等,所以欧拉函数就不好算了。我们把分母拎出来,并且使用公式 :

i=1ndj=1md[gcd(i,j)=1]=t=1ndμ(nd)ntdmtd

带入原式中,并且使用 T=td 替换:

=d=1nfdt=1ndμ(t)ntdmtd

=T=1n(d|Tfdμ(Td))nTmT

括号里面的就预处理,一个筛法,随便写。外面的根幂次有关的就考虑富比尼定理求解。时间复杂度 O(nlogn+Tn)

在知道了上面的小套路之后,简单的莫反(紫左右)大部分是可以写了。

下面再给出一些综合运用的例题:

[国家集训队]Crash的数字表格 / JZPTAB

P3327 [SDOI2015]约数个数和

最小公倍数之和

  • 这题中涉及到了另一个有意思的想法就是通过对序列中的数计数而转化为更一般的问题,请读者自行探索。有一点难。
posted @   Diavolo-Kuang  阅读(11)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示