dramforever

a row of my life

Möbius 反演

2017-03-18

本文使用 MathJax 渲染公式。如果过了好久以下这行还是不能正常显示那个优美而著名的公式的话,尝试进浏览器调试控制台 Network 栏看看咋回事吧

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

这是啥?

一堆 O(n)O(n) 数论题。

号称是莫比乌斯反演,同学都说是容斥是什么情况啊

为什么我的眼里常含泪水

Möbius 函数

μ(n)={0n1 (1)αn1α

当然有些性质

μ(1)=1 μ(p)=1(pP)

那个是“p是质数”的意思

μ(uv)=μ(u)μ(v)(gcd(u,v)=1)

然后就可以线性筛了对吧

好了,知道能算就行了

下面是最重要的那个式子啦

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

[P] 表示 P 这个 boolint 使的值

其它的一些基础内容


一般积性函数的线性筛

如果你知道 F(1),和如何比较方便地在 p/| u 时算出 F(pαu),那么就可以线性筛啦!

方法是,对每个数 pαu 维护这个数的最小质因子 p 是什么(线性筛 ftw),和这个质因子出现了多少次 α(发现(质数 zz|mcount[zm]=count[m]+1 就好了),还有除下这么多质数剩下的数 u。显然还是线性的,而且我们也确实维护出了需要的信息。


i=1ni

(没有上界。因为除着除着就没了)

对于任意一个 i,从 i 一直到 nn/ini 都是一样的。所以我们可以这么着分块算


i=1nimi

可以得出 nimi 总共有 O(n) 个取值(这里假定 nm 同阶)

为什么?因为 1 n 被下取整除法分成 O(n) 段,1 m 也是。总共被砍了 O(n) 刀,还是 O(n) 块。

对于一个 i,既然 ni 一样的最后一个是 nn/i,那俩都一样的肯定到 min(nn/i,mn/i)

枚举的时候要注意啦,for 那里的 i <= nnm 才正常。swap 一下就修好了。


做题


互质对

ni=1mj=1 [gcd(i,j)=1]

我们看到了可爱的 [???=1]

ni=1mj=1d|gcd(i,j)μ(d)

d|gcd(i,j) 就是两个都整除嘛。

ni=1mj=1d|id|jμ(d)

我们考虑枚举 d

dμ(d)ni=1mj=1 [d|id|j]

只有 d 的倍数的 ij 有贡献。我们换变量

dμ(d)ndi=1mdj=1 [d|did|dj]

条件永远为真

dμ(d)ndi=1mdj=1 1

1n 有哪些 d 的倍数。嗯这挺好办的。

dμ(d)n/di=1m/dj=1 1

数数好办

dμ(d)ndmd

预处理 μ 前缀和可 O(n) 预处理 O(n) 查询。


给定 gcd

ni=1mj=1 [gcd(i,j)=k]

显然 ij 都得是 k 的倍数

nki=1mkj=1 [gcd(ki,kj)=k] nki=1mkj=1 [gcd(i,j)=1]

1n 里 k 的倍数好啊

nki=1mkj=1 [gcd(i,j)=1]

然后就变成上一道题了。结论是

dμ(d)nkdmkd

gcd 求和

ni=1mj=1gcd(i,j)

考虑枚举 gcd 是啥,数有多少个,乘 gcd 再加起来就是求和啊

ggni=1mj=1 [gcd(i,j)=g]

代上一题结论

ggdμ(d)ngdmgd

我们枚举 gd 好不好啊

gd(d,gg μ(d))ngdmgd

这里的枚举 d,g 就是枚举相乘等于 dg 的数啦

预处理里面那个小求和 F(dg) 的前缀和可 O(n) 预处理 O(n) 查询。

注:可以证明 F(n)=φ(n),其中 φ 是欧拉函数


gcd 是质数的对数

pPni=1mj=1 [gcd(i,j)=p]

可以推出来一个类似上一题的结论

pd(pP,dμ(d))npdmpd

(本题中不再赘述 p 是质数)

我们来考虑一下 F(n)=p|nμ(n/p) 的性质。

对于 zP,z/| u

F(zu)=p|zuμ(zu/p)=μ(u)+p|uμ(zu/p)=μ(u)+p|uμ(u/p)=μ(u)p|uμ(u/p)=μ(u)F(u)

但是如果 z|u,那么只要 pzzu/p 就有平方因子 z2,所以就挂掉了

F(zu)=p|zuμ(zu/p)=μ(u)+p|uμ(zu/p)=μ(u)

预处理 F(pd) 的前缀和可 O(n) 预处理 O(n) 查询。


lcm 求和

ni=1mj=1lcm(i,j)

往下推呗

ni=1mj=1lcm(i,j)=dni=1mj=1ijd[gcd(i,j)=d]=dndi=1mdj=1d2ijd[gcd(di,dj)=d]=dn/di=1m/dj=1d2ijd[gcd(i,j)=1]=ddn/di=1m/dj=1ij [gcd(i,j)=1]

然后我们像上面那样枚举 gcd(i,j)=ui 偷换成 uij 偷换成 uj

=uμ(u)dn/dui=1m/duj=1u2dij=uμ(u)du2(n/dui=1i)(m/duj=1j)=du(d,udu2μ(u))n/du(1+n/du)2m/du(1+m/du)2=dudu (d,uu μ(u))n/du(1+n/du)2m/du(1+m/du)2

预处理 du (d,uu μ(u)) 前缀和可 O(n) 预处理 O(n) 查询。