莫比乌斯反演 学习笔记

模板及讲解

整数分块

求 $\sum_{i=1}^n \lfloor \frac ni \rfloor$。

显然可以暴力$O(n)$求。但是这里可以$O(\sqrt n)$ 求。

结论:对于所有的 $\lfloor \frac ni \rfloor$ 都是一段连续的块,并且块的端点可以被枚举。假设当前在 $i$ 处,那么 $\lfloor \frac ni \rfloor$的最后一个值在$\lfloor \frac{n}{\lfloor \frac ni \rfloor} \rfloor$

证明:设$\lfloor \frac ni \rfloor = \lfloor \frac n{i’} \rfloor=k$,并且$i’$为最大的位置。
设$i+d=i’$,$n=ik+p,n=(i+d)k+p’$
可得$p’=p-dk$,则$d_{max}= \lfloor \frac pk \rfloor$
那么$i’=i+d_{max}$
$$
=i+ \left \lfloor \frac pk \right \rfloor=i+\left\lfloor \frac {n\%i}{\left\lfloor \frac ni \right\rfloor} \right\rfloor=\left\lfloor i+ \frac {n\%i}{\left\lfloor \frac ni \right\rfloor} \right\rfloor=\left\lfloor \frac {i \cdot \left\lfloor \frac ni \right\rfloor}{\left\lfloor \frac ni \right\rfloor}+ \left\lfloor \frac {n\%i}{\left\lfloor \frac ni \right\rfloor} \right \rfloor \right\rfloor
$$

$$
= \left\lfloor \frac {i \cdot \left\lfloor \frac ni \right\rfloor+n-\left\lfloor \frac ni \right\rfloor \cdot i}{\left\lfloor \frac ni \right\rfloor} \right\rfloor= \left\lfloor \frac {n}{\left\lfloor \frac ni \right\rfloor} \right\rfloor
$$

得证。
易得$\lfloor \frac ni \rfloor$取值不超过$2\sqrt n$ 个,所以复杂度为$O(\sqrt n)$。

例题:Bzoj 1968

LL l = 1, r, ans = 0ll;
while (l <= n) {
    r = (n / (n / l));
    ans += (r - l + 1ll) * (n / l);
    l = r + 1ll;
}

Bzoj 1257

给出 $n, k$,求$\sum_{i=1}^n k \mod i$

$k \mod i= k -i \cdot \lfloor \frac ki \rfloor$,则$\sum_{i=1}^n k \mod i= \sum_{i=1}^n k -i \cdot \lfloor \frac ki \rfloor=nk-\sum^{n}_{i=1} i \cdot \lfloor \frac ki \rfloor$

发现右边是整除分块的形式,所以加一个等差数列求和公式计算即可。注意此题要判断一下$n,k$的大小。复杂度$O(\sqrt n)$

LL ans = 0ll, l = 1, r;
if (n > k) ans += (n - k) * k, n = k;
ans += n * k;
while (l <= n) {
    r = min(n, (k / (k / l)));
    ans -= (l + r) * (r - l + 1ll) / 2ll * (k / l);
    l = r + 1ll;
}

此题有升级版,Blog,$T(T \leq 10^6)$组询问$n(n \leq 10^6)$。此时用整除分块会炸。考虑$i \cdot \lfloor \frac ki \rfloor$的意义就是因数和。所以线性筛因数和即可。预处理前缀和后$O(1)$ 处理询问。

线性筛积性函数

线性筛积性函数考虑两个
第一个是$f(p), p$为质数是的取值怎么$O(1)$算
第二个是$f(p^x), p$为质数是的取值怎么$O(1)$算,也就是说我们需要从$f(p^x)$转到$f(p^{x+1})$怎么求

第一个:在某数为质数时需要$O(1)$算出函数值
第二个:线性筛是用最小质因数去筛数,所以对于被筛的数在$p|i$时只需要考虑$f(p^x)$转到$f(p^{x+1})$怎么求
而$gcd(i,p)=1$时利用积性函数性质进行求解即可。

莫比乌斯函数

若 $i=p_1^{a_1}p_2^{a_2}\cdots p_k^{a_k}$,那么有莫比乌斯函数

$$
\mu(i)=
\begin{cases}
1&,i=1 \\
(-1)^k&,\forall a_k=1 \\
0&,\exists a_k\gt1
\end{cases}
$$

性质

1、莫比乌斯函数是积性函数

$μ(a)μ(b)=μ(ab),a⊥b$

运用此性质可以线性筛莫比乌斯函数。

2

$$
\sum_{d\mid n}\mu(d) = [n = 1]​
$$

证明:(二项式定理)

设$n$有$k$种因子。则

$$
\sum_{d\mid n}\mu(d)=\sum_{i=0}^kC^i_k(-1)^i1^{k-r}=[n=1]
$$

线性筛莫比乌斯函数

时间复杂度 $ O(n) $。
有更优秀的杜教筛。

mu[1] = 1, vis[1] = 1; // mu[1] = 1
for (int i = 2; i <= n; ++i) {
    if (!vis[i]) pri[++tot] = i, mu[i] = -1; // 奇数个 mu[i] = -1
    for (int j = 1; j <= tot && (LL)i * (LL)pri[j] <= (LL)n; ++j) {
        vis[i * pri[j]] = 1;
        if (i % pri[j] == 0) {
          mu[i * pri[j]] = 0;  // 一个质因子多个 mu[i] = 0
          break;
        } else mu[i * pri[j]] = -mu[i]; // 积性函数
    }
}

莫比乌斯反演

定义

$g(n)$和$f(n)$是定义在非负整数集合上的两个函数

1、当$$g(n)=\sum_{d|n}f(d)$$

那么有莫比乌斯反演

$$
f(n)=\sum_{d|n}\mu(d)g(\frac{n}{d})
$$

2、当$g(i)=\sum^{\frac ni}_{d=1}f(d \cdot i)$

那么有莫比乌斯反演

$$
f(i)=\sum_{d=1}^{\frac ni}g(d \cdot i)\mu(d)
$$

证明

$$
\sum_{d|n}\mu(d)g(\frac{n}{d})=\sum_{d|n}\mu(d)\sum_{i|\frac{n}{d}}f(i)=\sum_{i|n}f(i)\sum_{d|\frac{n}{i}}\mu(d)=f(n)
$$

证明都是用将 $\mu(k)$ 提后然后根据性质1判断。

变形

欧拉函数变形

$$
\varphi(n)=\sum_{i=1}^n[\gcd(i,n)=1]=\sum_{i=1}^n\sum_{k\mid i,k\mid n}\mu(k)=\sum_{k\mid n}\mu(k)\lfloor\frac nk\rfloor
$$

运用

求 $\gcd = k$ 的个数

例题:Bzoj 2301
题意:给定$a, b, c, d, k$, 求
$$
\sum_{i=a}^{b} \sum_{j=c}^{d} [\gcd(i,j)=k]
$$

(下面默认$n \leq m$, 不满足则交换)
解:
我们可以将答案分成几个部分求解,然后$ans=f(b,d)-f(a-1,d)-f(b,c-1)+f(a-1,c-1)$
依题意设出$f(k)$为$gcd(i,j)=k$的个数$(1 \leq i \leq n, 1 \leq j \leq n)$
但是这个并不好求,看见两个求和符号,我们可以想到用莫比乌斯反演来求解。
显然用变形后的两个式子,我们就可以设$g(k)$为$k|gcd(i,j)$的个数$(1 \leq i \leq n, 1 \leq j \leq n)$
$g(k)$非常好算,$g(k)=\lfloor \frac n{k} \rfloor \lfloor \frac m{k} \rfloor$
而显然$g(k)=\sum_{d=1}^{\lfloor \frac nk \rfloor} f(ki)$
那么可以莫比乌斯反演
$$
f(k)=\sum_{d=1}^{\lfloor \frac nk \rfloor} \mu(d) \lfloor \frac n{kd} \rfloor \lfloor \frac m{kd} \rfloor
$$
换元$\lfloor \frac nk \rfloor$,整除分块即可。

注意有$n,m$的整除分块是取两者最小值,复杂度也是有保证的。

求 $\gcd(i,j)$ 的和

例题:Bzoj 2005
题意:
给定$n,m$,求
$$
\sum_{i=1}^n\sum_{j=1}^m \gcd(i,j)
$$

按照套路反演以后得到

$$
\sum_{d=1}^n d \sum_{i=1}^{\lfloor \frac nd \rfloor} \mu(i) \lfloor \frac n{di} \rfloor \lfloor \frac m{di}\rfloor
$$

然后我们设$T=di​$,则

$$
\sum_{T=1}^n \lfloor \frac nT \rfloor \lfloor \frac mT \rfloor \sum_{d|T} \mu(d) \lfloor \frac Tk \rfloor
$$

设$h(T)=\sum_{d|T} \mu(d) \lfloor \frac Tk \rfloor$,则可以线性筛。

也可以发现这就是欧拉函数,直接筛欧拉函数即可。

求 $\gcd(i,j)^k$ 的和

例题:BZOJ 4407
题意:
给定$n,m,k$,求
$$
\sum_{i=1}^n\sum_{j=1}^m \gcd(i,j)^k \mod (10^9+7)
$$

按照套路反演以后得到

$$
\sum_{d=1}^n d^k \sum_{i=1}^{\lfloor \frac nd \rfloor} \mu(i) \lfloor \frac n{di} \rfloor \lfloor \frac m{di}\rfloor
$$

此时我们发现可以分块套分块达到复杂度$O(n)$单次询问。
但是还是不够,那么继续变形

设$T=di$,则

$$
\sum_{T=1}^n \lfloor \frac nT \rfloor \lfloor \frac mT \rfloor \sum_{d|T} d^k \mu(\frac Td)
$$

设$f(T)=\sum_{d|T}d^k \mu(\frac Td)$,发现$d^k$和$\mu(k)$都是积性函数,所以乘积也是积性函数,所以我们可以线性筛$O(n)$算这个积性函数值。

如何线性筛?
线性筛积性函数考虑两个
第一个是$f(p), p$为质数时的取值怎么$O(1)$算
第二个是$f(p^x), p$为质数时的取值怎么$O(1)$算,也就是说我们需要从$f(p^x)$转到$f(p^{x+1})$怎么求

考虑将$T$质因数分解,那么对于每个$p_i$

$$
f(p_i^{x_i})=\sum_{d|p_i^{x_i}}d^k\mu(\frac{p_i^{x_i}}d)
$$

因为有$\mu$的存在,只需要考虑$d=p_i^{x_i}$和$d=p_i^{x_i-1}$的情况,则原式化为

$$
f(p_i^{x_i})=\mu(p_i) \cdot p_i^{k(x_i-1)} + \mu(1) \cdot p_i^{x_ik}
$$

$$
f(p_i^{x_i}) = p_i^{x_ik} - p_i^{k(x_i-1)}
$$

$$
f(p_i^{x_i}) = p_i^{k(x_i-1)}(p_i^k-1)
$$

这个式子可以方便解决$f(p^x), p$为质数时的取值

对于第一个,$f(p)=\mu(1) \cdot p^k + \mu(p) \cdot 1^k=p^k-1$

那么这样就可以线筛了。

求 $\operatorname{lcm}(i,j)$ 的和

例题:BZOJ 2154
题意:给定$n, m$,求
$$
\sum_{i=1}^n \sum_{j=1}^m \operatorname{lcm}(i, j)
$$

化为$\gcd$式子
$$
\sum_{d=1}^n d \sum_{i=1}^{n}\sum_{j=1}^{m}\frac{ij}{\gcd(i,j)} \\
\sum_{d=1}^n d \sum_{i=1}^{\lfloor \frac nd \rfloor}\sum_{j=1}^{\lfloor \frac md \rfloor}ij \cdot [\gcd(i,j)=1]
$$

$$
f(n,m)=\sum_{i=1}^n \sum_{j=1}^m ij \cdot [\gcd(i,j)=1] \\
=\sum_{d=1}^n \sum_{d|i} \sum_{d|j} \mu(d) \cdot d^2 \sum_{i=1}^{\lfloor \frac nd \rfloor}\sum_{j=1}^{\lfloor \frac md \rfloor}ij
$$
设 (两个等差数列相乘)
$$
g(n,m)=\sum_{i=1}^n \sum_{j=1}^m ij =\frac{n(n+1)}{2} \times \frac{m(m+1)}{2}
$$

$$
f(n,m)=\sum_{d=1}^n \mu(d) \cdot d^2 \cdot g(\lfloor \frac nd \rfloor, \lfloor \frac md \rfloor)
$$
即原式为
$$
\sum_{d=1}^m d \cdot f(\lfloor \frac nd \rfloor, \lfloor \frac md \rfloor)
$$

计算$f(n,m)$时整除分块,计算答案时整除分块,时间复杂度$O(n+m)$

求$f(gcd(i,j))$的和

例题:BZOJ 3529
题意:给定多组$n,m,a$,设$d_1(n)$为$n$约数和,求
$$
\sum_{i=1}^n \sum_{j=1}^m d_1(\gcd(i, j))
$$
并且满足$d_1(\gcd(i, j)) \leq a$

不考虑$a$的限制,枚举约数
$$
\sum_{d=1}^n \sum_{i=1}^n \sum_{j=1}^m d_1(d)[gcd(i,j)=d])
$$
发现$d_1(d)$与$i,j$无关,移到前面
$$
\sum_{d=1}^n d_1(d) \sum_{i=1}^n \sum_{j=1}^m [gcd(i,j)=d])
$$
将后面用反演套路化简,得
$$
\sum_{d=1}^n d_1(d) \sum_{k=1}^{\lfloor \frac nd \rfloor} \mu(k) \lfloor \frac n{kd} \rfloor \lfloor \frac m{kd} \rfloor
$$
设$T=kd$,则
$$
\sum_{T=1}^n \lfloor \frac nT \rfloor \lfloor \frac mT \rfloor \sum_{d|T}d_1(d) \mu(\frac Td)
$$
如果没有$a$的限制,则线性筛后面的函数即可。
考虑$a$的限制。
只有$d_1(x) \leq a$的才会有贡献。
所以将$d_1(x)$从小到大排序,将询问离线后按$a$从小到大排序
每次按照$a$的单增补齐到$a$,补齐即枚举$x$的倍数进行增加。
维护一个单调修改区间查值的数据结构,用树状数组维护之。
时间复杂度:$O(n\log ^2 n + q \sqrt n \log n)$

总结

莫比乌斯反演一般是
1、两个求和符号
2、用反演公式设出与所求的那个函数符合的函数,然后导出基本式子
3、用技巧(换元、内层外移、观察、莫比乌斯函数容斥性等)来化简式子
4、最后的答案整除分块,必要时将与外层枚举变量无关的式子证明是积性函数线性筛无法证明则打表验证,重点关注质数,质数的幂的值

莫比乌斯反演的套路
1、换元,比如设$T=kd$
2、内层外移 (换元后、枚举约数$\Leftrightarrow$直接枚举)
3、设新函数线性筛/反演/处理:比如设$h(T)=\sum_{d|T} \mu(d) \lfloor \frac nk \rfloor$
4、观察法:一般是观察$\mu$的取值造成的影响
5、化布尔式为$\mu$式子 (例子:$[n=1] \Leftrightarrow \sum_{d|n} \mu(d)$)
6、构造$[\gcd(i,j)=k]$反演

Dirichlet 卷积

常见的完全积性函数

1、$\epsilon(x)$:Dirichlet卷积的乘法单位元,完全积性。$\epsilon(x) = [x = 1]$
2、$I(n)$:恒等函数,完全积性。$I(n)=1$
3、$id(n)$:单位函数,完全积性。$id(n)=n$
4、$id^k(n)$:幂函数,完全积性。$id^k(n)=n^k$

定义

数论函数$f$和$g$的Dirichlet卷积定义为
$$
(f∗g)(n)=\sum_{d|n}f(d) g(\frac nd)
$$

满足交换律、结合律、分配律,证明此处略去。

性质

1、如果 $f$ 和 $g$ 均为积性函数,那么 $f∗g$ 一定也为积性函数

2、任何数论函数$f$卷上$I$代表$\sum\limits_{d|n} f(d)$,卷上$id$代表$\sum\limits_{d|n} f(d) \cdot \frac di $,$id^k$类似

3、任何数论函数$f$卷上$\epsilon$还是原函数$f$,所以就验证了$\epsilon$是单位元。

4、$\mu * I = \epsilon$

根据$\sum \limits_{d|n} {\mu(d)} = [n =1]$即可证明。

5、$\varphi * I = id$

根据$\sum \limits_{d | n} {\varphi(d) = n}$即可证明。

6、$\varphi = id * \mu$ ($\mu$与$\varphi$关系)

由$\varphi * I = id$,两边卷$\mu$
$$\varphi * I * \mu = id * \mu$$

$$\varphi = id * \mu$$

7、$\frac{\varphi(n)}{n} = \sum \limits_{d | n} {\frac{\mu(d)}{d}}$ ($\mu$与$\varphi$关系)

由$\varphi = id * \mu$
$$\varphi(n) = \sum \limits_{d | n} {\mu(d) \times \frac{n}{d}}$$
将两边同时除以 $n$
$$\frac{\varphi(n)}{n} = \sum \limits_{d | n} {\frac{\mu(d)}{d}}$$

证明莫比乌斯反演

根据定义
$$
f = g * I
$$
两边卷上$\mu$
$$
f * \mu = g * I * \mu
$$
由$\mu * I = \epsilon$
$$
f * \mu = g * \epsilon \\
g = f * \mu
$$
得证。

杜教筛

模板题:Bzoj 3944 杜教筛Sum
给定一个正整数$n$,求
$$
\sum_{i=1}^n \varphi(i) \\
\sum_{i=1}^n \mu(i)
$$

设$f$是我们要求前缀和的积性函数,设$S(n)=\sum_{i=1}^n$
找一个$g$卷上$f$
$$
\sum_{i=1}^n (f * g)(n)
$$
Dirichlet 卷积定义转化
$$
\sum_{i=1}^n \sum_{d|i} f(d)g(\frac id)
$$
先枚举$d$
$$
\sum_{d=1}^n g(d) \sum_{i=1}^{\lfloor \frac nd \rfloor} f(i)
$$
用$S$改写
$$
\sum_{d=1}^n g(d)S(\lfloor \frac nd \rfloor)
$$
考虑 (两个前缀和相减)
$$
g(1)S(n)=\sum_{i=1}^n(f * g)(n) - \sum_{i=2}^n g(i)S(\lfloor \frac ni \rfloor)
$$
那么找到一个合适的$g$,能快速求出$f * g$的前缀和,则就能递归+整除分块快速求出$f$的前缀和。

这个算法复杂度$O(n^{\frac 34})$
预处理出前$m=n^{\frac 23}$个前缀和,可以使复杂度变为$O(n^{\frac 23})$
(这个也不是限定死的,可以尽量往大开)

1、求$\sum\limits_{i=1}^n \varphi(i)$

由$\varphi * I = id$,得
$$
\sum_{i=1}^n \varphi(i)=\frac{n(n + 1)}{2}-\sum_{i=2}^n \varphi(\lfloor \frac ni \rfloor)
$$

2、求$\sum\limits_{i=1}^n \mu(i)$

由$\mu * I = \epsilon$,得
$$
\sum_{i=1}^n \mu(i)=1-\sum_{i=2}^n \mu(\lfloor \frac ni \rfloor)
$$

#include<cstdio> 
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
#include<map>
#include<string>
#define ms(i, j) memset(i, j, sizeof i)
#define LL long long
#define db long double
#define fir first
#define sec second
#define mp make_pair
using namespace std;


namespace flyinthesky {

    const LL N = 5000000;

    int vis[N + 5], pri[400000 + 5], tot;
    LL mu[N + 5], phi[N + 5];
    LL T;
    map<int, LL > ansphi, ansmu;

    LL getphi(int n) {
        if (n <= N) return phi[n];
        if (ansphi[n]) return ansphi[n];
        LL ret = 1ll * n * (n + 1ll) / 2ll;
        int l = 2;
        while (l <= n) {
            int r = n / (n / l);
            ret -= 1ll * (r - l + 1ll) * getphi(n / l);
            if (r == 2147483647) break ;
            l = r + 1;
        }
        return ansphi[n] = ret;
    }
    LL getmu(int n) {
        if (n <= N) return mu[n];
        if (ansmu[n]) return ansmu[n];
        LL ret = 1ll; // ²»ÊÇ [n=1] 
        int l = 2;
        while (l <= n) {
            int r = n / (n / l);
            ret -= 1ll * (r - l + 1ll) * getmu(n / l);
            if (r == 2147483647) break ;
            l = r + 1;
        }
        return ansmu[n] = ret;
    }

    void init() {
        ms(vis, 0), ms(pri, 0), tot = 0, ms(mu, 0), ms(phi, 0);
        mu[1] = 1, phi[1] = 1;
        for (int i = 2; i <= N; ++i) {
            if (!vis[i]) pri[++tot] = i, mu[i] = -1, phi[i] = i - 1;
            for (int j = 1; j <= tot && 1ll * pri[j] * i <= 1ll * N; ++j) {
                vis[pri[j] * i] = 1;
                if (i % pri[j] == 0) {
                    mu[i * pri[j]] = 0;
                    phi[i * pri[j]] = phi[i] * pri[j];
                    break ;
                } else mu[i * pri[j]] = mu[i] * mu[pri[j]], phi[i * pri[j]] = phi[i] * phi[pri[j]];
            }
        }
        for (int i = 2; i <= N; ++i) mu[i] += mu[i - 1], phi[i] += phi[i - 1];
    }
    void clean() {
    }
    int solve() {

        clean();
        scanf("%lld", &T);
        while (T--) {
            LL n; scanf("%lld", &n);
            printf("%lld %lld\n", getphi(n), getmu(n));
        }

        return 0;
    }
}
int main() {
    flyinthesky::init();
    flyinthesky::solve();
    return 0;
}

常见题型

------ 本文结束 ------