专栏文章

莫比乌斯反演

算法·理论参与者 6已保存评论 5

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
5 条
当前快照
1 份
快照标识符
@minngyed
此快照首次捕获于
2025/12/02 05:17
3 个月前
此快照最后确认于
2025/12/02 05:17
3 个月前
查看原文
本文的重点不是处理式子,只是希望带给你一种莫反的新理解。

问题

像各种反演模型一样,莫比乌斯反演是一种代替容斥的强大工具。 它解决的问题如下:如果已知 fk=dkgdf_k = \sum_{d | k}g_d,那么 gk=dkf(kd)μ(d)g_k = \sum_{d | k}f({k \over d})\mu(d)

莫比乌斯函数是容斥系数

正整数是一个以质数为基底的高维空间。对于 n=piαin = \prod p_i^{\alpha_i},我们认为它的坐标是 (α1,α2,,αi,)(\alpha_1, \alpha_2, \cdots, \alpha_i, \cdots)。可以发现,上述 fkf_k 的定义就是此意义下的高维前缀和,现在,我们想根据高维前缀和求出原数组。
类比二维的情况,ai,j=sumi,jsumi1,jsumi,j1+sumi1,j1a_{i, j} = sum_{i, j} - sum_{i - 1, j} - sum_{i, j - 1} + sum_{i - 1, j - 1},稍微手玩一下三维的,我们发现对于维度是 nn 的情况来说,g(α1,α2,,αn)=S{1,2,,n}(1)Sf(α1[1S],,αi[iS],,αn[nS])g_{(\alpha_1, \alpha_2, \cdots, \alpha_n)} = \sum_{S \subset \{1, 2, \cdots, n \} } (-1)^{|S|} f_{(\alpha_1 - [1 \in S], \cdots, \alpha_{i} - [i \in S], \cdots, \alpha_n - [n \in S])}。证明由容斥原理易得。
转化成整除式的表达,gk=dkf(kd)μ(d)g_k = \sum_{d | k}f({k \over d})\mu(d),这个 dd 就类比上面的 SS,也就是挑一些维度减去 1。也就是说,如果 ddtt 个本质不同的质因子,那么这个就是容斥系数 (1)t(-1)^t。但到这就完了吗?如果 p,p2d\exists p, p^2 | d 那也就意味着,我们至少挑了一些维度把这一维的坐标减去了 2,根据上面的式子,减 2 对于最终答案是没有任何贡献的。因此这种 dd 的系数就应该是 00
整理一下:
0,& \exists p^2 | d(p > 1) \\ (-1)^k, & d \text{ is a product of } k \text{ distinct primes} \end{cases}
这就是莫比乌斯函数的定义了。

一些性质

  1. 莫比乌斯函数是积性函数
容易验证。
  1. dnμ(d)=[n=1]\sum_{d | n} \mu(d) = [n = 1]
n=i=1kpiαin = \prod_{i = 1}^k p_i^{\alpha_i}n=i=1kpin' = \prod_{i = 1}^k p_i。 那么 dnμ(d)=dnμ(d)=i=0k(ki)(1)i=[k=0]\sum_{d|n} \mu(d) = \sum_{d | n'} \mu(d) = \sum_{i = 0}^k {k \choose i}(-1)^i = [k = 0]。 这条性质的本质是由于莫比乌斯函数是上面提到的容斥系数决定的(你会发现这个推导过程跟证明容斥/凑容斥的过程很类似)。
2 性质有一个重要的应用,即 [gcd(i,j)=1]=d[di][dj]μ(d)[\gcd(i, j) = 1] = \sum_d [d | i][d | j] \mu(d) 这个在推式子时很常用。
同时,2 性质用 Dirichlet 的语言可以描述为 ε=1μ\varepsilon = 1 * \mu。(ε(n)=[n=1]\varepsilon(n) = [n = 1],有性质 f,fε=f\forall f, f * \varepsilon = f)

莫比乌斯反演的倍数拓展形式

刚刚提到的形式是针对高维前缀和的,实际上把刚刚的过程全部改成高维后缀和也是没有问题的(甚至可以变成前缀积)。
fd=dkgk    gd=dkfkμ(kd)f_d = \sum_{d | k} g_k \iff g_d = \sum_{d | k} f_k \mu({k \over d})
从这个角度理解 oi-wiki 上的各种拓展形式或许就自然了许多。

一道例题

莫比乌斯反演的题大部分都是推式子,给一道感受一下吧。
P1829: 求 i=1nj=1mlcm(i,j)\sum_{i = 1}^n\sum_{j = 1}^m \operatorname{lcm}(i, j)
首先,我们擅长的是处理 gcd\gcd。 那么把原式变成:
i=1nj=1mi×jgcd(i,j)=k=1n1ki=1nj=1m[gcd(i,j)=k](i×j)=k=1n1ki=1nj=1m[ki][kj][gcd(ik,jk)=1](i×j)=k=1n1ki=1nkj=1mk[gcd(i,j)=1](ik×jk)=k=1nki=1nkij=1mkj[gcd(i,j)=1]=k=1nki=1nkij=1mkjd[di][dj]μ(d)=k=1nkdμ(d)i=1nk[di]ij=1mk[dj]j\begin{aligned} \sum_{i = 1}^n \sum_{j = 1}^m \frac{i \times j}{\gcd(i, j)} &= \sum_{k = 1}^n \frac{1}{k} \sum_{i = 1}^n \sum_{j = 1}^m [\gcd(i, j) = k](i \times j) \\ &= \sum_{k = 1}^n \frac{1}{k} \sum_{i = 1}^n \sum_{j = 1}^m [k | i][k | j][\gcd({i \over k}, {j \over k}) = 1](i \times j) \\ &= \sum_{k = 1}^n \frac{1}{k} \sum_{i' = 1}^{\lfloor \frac{n}{k} \rfloor} \sum_{j' = 1}^{\lfloor \frac{m}{k} \rfloor} [\gcd(i', j') = 1](i'k \times j'k) \\ &= \sum_{k = 1}^n k \sum_{i' = 1}^{\lfloor \frac{n}{k} \rfloor} i' \sum_{j' = 1}^{\lfloor \frac{m}{k} \rfloor} j' [\gcd(i', j') = 1] \\ &= \sum_{k = 1}^n k \sum_{i' = 1}^{\lfloor \frac{n}{k} \rfloor} i' \sum_{j' = 1}^{\lfloor \frac{m}{k} \rfloor} j' \sum_d [d | i'][d | j']\mu(d) \\ &= \sum_{k = 1}^n k \sum_d \mu(d) \sum_{i' = 1}^{\lfloor \frac{n}{k} \rfloor} [d | i'] i' \sum_{j' = 1}^{\lfloor \frac{m}{k} \rfloor} [d | j']j' \end{aligned}
G(x)=i=1x[di]iG(x) = \sum_{i = 1}^x[d | i]i,实际上是一个等差数列求和,G(x)=12(d+d×xd)xd=d×12×(1+xd)xd:=d×g(xd)G(x) = \frac{1}{2}(d + d \times \lfloor \frac{x}{d} \rfloor) \lfloor \frac{x}{d} \rfloor = d \times \frac{1}{2} \times (1 + \lfloor \frac{x}{d} \rfloor) \lfloor \frac{x}{d} \rfloor := d \times g(\lfloor \frac{x}{d} \rfloor)。带回原式,并根据 abc=abc\lfloor {{\lfloor {a \over b} \rfloor} \over c} \rfloor = \lfloor \frac{a}{bc} \rfloor 得到: k=1nkdμ(d)d2g(nkd)g(mkd)\sum_{k = 1}^n k \sum_d \mu(d)d^2 g(\lfloor \frac{n}{kd} \rfloor) g(\lfloor \frac{m}{kd} \rfloor) 根据 oi-wiki 的技巧,此时经常用 l=k×dl = k \times d 进行替换,即: l=1nlg(nl)g(ml)dlμ(d)d\sum_{l = 1}^n l g(\lfloor \frac{n}{l} \rfloor) g(\lfloor \frac{m}{l} \rfloor) \sum_{d | l} \mu(d)d
记录 f(l)=dlμ(d)df(l) = \sum_{d | l} \mu(d)d,首先 h(d)=μ(d)dh(d) = \mu(d)d 是积性函数(积性函数的积还是积性函数),那么 f=h1f = h * 1 也是积性函数。那么我们线性筛 ff 即可。最后遍历一遍 ll 求出答案。
复杂度 O(n)O(n)
CPP
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e7 + 5, mod = 20101009, i2 = 10050505;
bitset<N> vis;
int pri[N], cnt, g[N], f[N];
int G(int x){
    return x * (x + 1) % mod * i2 % mod;
}
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    int n, m;
    cin >> n >> m;
    f[1] = 1;
    if(n > m) swap(n, m);
    for(int i = 2; i <= n; ++i){
        if(!vis[i]){
            pri[++cnt] = i;
            f[i] = 1 - i;
            g[i] = i;
        } 
        for(int j = 1; j <= cnt; ++j){
            if(i * pri[j] > n) break;
            int nxt = i * pri[j];
            vis[nxt] = 1;
            if(i % pri[j] == 0){
                g[nxt] = g[i] * pri[j];
                f[nxt] = (f[nxt / g[nxt]] * f[pri[j]]) % mod;
                break;   
            }
            g[nxt] = pri[j];
            f[nxt] = (f[nxt / pri[j]] * f[pri[j]]) % mod;
        }
    }
    int ans = 0;
    for(int l = 1; l <= n; ++l){
        (ans += G(n / l) * G(m / l) % mod * l % mod * f[l] % mod) %= mod;
    }
    cout << (ans % mod + mod) % mod;
    return 0;
}

评论

5 条评论,欢迎与作者交流。

正在加载评论...