莫比乌斯反演

本文深入解析了莫比乌斯反演的数学原理及其在数论问题中的应用,包括狄利克雷卷积、数论分块等概念,并通过具体例题展示了如何运用这些理论解决实际问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

莫比乌斯反演-OIWiki
数论分块:对于 ⌊ n i ⌋ \lfloor \frac{n}{i} \rfloor in ,要找一个最大的值 j j j ,使得 j = ⌊ n i ⌋ j=\lfloor \frac{n}{i} \rfloor j=in 。这个 j = ⌊ n ⌊ n i ⌋ ⌋ j=\lfloor \frac{n}{\lfloor \frac{n}{i} \rfloor} \rfloor j=inn 。由于 ⌊ n i ⌋ \lfloor \frac{n}{i} \rfloor in 最多有 n \sqrt n n 种取值,因此可以分成 n \sqrt n n 个块。

狄利克雷卷积: ( f ∗ g ) ( n ) = ∑ d ∣ n f ( d ) g ( n d ) (f *g)(n)=\sum_{d|n}f(d)g(\frac{n}{d}) (fg)(n)=dnf(d)g(dn)
可以推出 μ ∗ 1 = ∑ d ∣ n μ ( d ) = ∑ i = 0 k ( − 1 ) k ( k i ) \mu * 1= \sum_{d|n}\mu(d) = \sum_{i=0}^k(-1)^k\tbinom{k}{i} μ1=dnμ(d)=i=0k(1)k(ik) ,假设 k k k n n n 的不同质因子个数。
( x + y ) k = ∑ i = 0 k x i y k − i ( k i ) (x+y)^k=\sum_{i=0}^kx^iy^{k-i}\tbinom{k}{i} (x+y)k=i=0kxiyki(ik) ,当 x = − 1 , y = 1 x=-1,y=1 x=1,y=1 时,得到 0 k = ∑ i = 0 k ( − 1 ) k ( k i ) 0^k=\sum_{i=0}^k(-1)^k\tbinom{k}{i} 0k=i=0k(1)k(ik) ,而 0 k 0^k 0k k = 1 k=1 k=1 时为 1 1 1 ,其他时候为 0 0 0 。因此 μ ∗ 1 = ε = [ n = 1 ] \mu * 1=\varepsilon=[n=1] μ1=ε=[n=1]
由上可知, [ g c d ( i , j ) = 1 ] = ∑ d ∣ g c d ( i , j ) μ ( d ) [gcd(i,j)=1]=\sum_{d|gcd(i,j)} \mu (d) [gcd(i,j)=1]=dgcd(i,j)μ(d)

莫比乌斯反演: g ( n ) = ∑ d ∣ n f ( d ) g(n) = \sum_{d|n}f(d) g(n)=dnf(d) -> f ( n ) = ∑ d ∣ n μ ( d ) g ( n d ) f(n)=\sum_{d|n} \mu (d) g (\frac{n}{d}) f(n)=dnμ(d)g(dn)
证明: g = f ∗ 1 g = f *1 g=f1 。两边都卷积上 μ \mu μ 时, μ ∗ g = f ∗ 1 ∗ μ \mu * g = f * 1 * \mu μg=f1μ 。由于狄利克雷卷积满足结合律和交换律且 μ ∗ 1 = ε \mu * 1 = \varepsilon μ1=ε , 则 f ∗ 1 ∗ μ = f ∗ ε = f f * 1 * \mu = f * \varepsilon = f f1μ=fε=f,因此 f = μ ∗ g f=\mu * g f=μg 。莫比乌斯反演得证。

例题:
BZOJ-2301:
求: ∑ i = x n ∑ j = y m [ g c d ( i , j ) = k ] \sum_{i=x}^n\sum_{j=y}^m[gcd(i,j)=k] i=xnj=ym[gcd(i,j)=k]
可以转为求 ∑ i = 1 n ∑ j = 1 m [ g c d ( i , j ) = k ] \sum_{i=1}^n\sum_{j=1}^m[gcd(i,j)=k] i=1nj=1m[gcd(i,j)=k] 然后容斥求答案。前式可以转化为: ∑ i = 1 n / k ∑ j = 1 m / k [ g c d ( i , j ) = 1 ] \sum_{i=1}^{n/k}\sum_{j=1}^{m/k}[gcd(i,j)=1] i=1n/kj=1m/k[gcd(i,j)=1] 。然后可以转为为 ∑ i = 1 n / k ∑ j = 1 m / k ∑ d ∣ g c d ( i , j ) μ ( d ) \sum_{i=1}^{n/k}\sum_{j=1}^{m/k} \sum_{d|gcd(i,j)} \mu (d) i=1n/kj=1m/kdgcd(i,j)μ(d) 。假设 n &lt; m n&lt;m n<m ,将 d d d 提到最外面得到: ∑ d = 1 n / k μ ( d ) ∑ i = 1 n / k [ i ≡ 0 ( m o d d ) ] ∑ j = 1 m / k [ j ≡ 0 ( m o d d ) ] \sum_{d=1}^{n/k} \mu (d)\sum_{i=1}^{n/k} [i \equiv 0 \pmod{d}] \sum_{j=1}^{m/k} [j \equiv 0 \pmod{d}] d=1n/kμ(d)i=1n/k[i0(modd)]j=1m/k[j0(modd)] 。后面两项就是求有多少个 i i i j j j d d d 的倍数,因此可以转化为 ∑ d = 1 n / k μ ( d ) × ( n / ( k d ) ) × ( m / ( k d ) ) \sum_{d=1}^{n/k} \mu (d) \times (n/(kd)) \times (m/(kd)) d=1n/kμ(d)×(n/(kd))×(m/(kd)) 。然后就可以求出 μ \mu μ 的前缀和,然后数论分块来做。

#include <bits/stdc++.h>
using namespace std;
const int N = 5e4+7;
int mu[N], p[N];
bool nop[N];
void init() {
    int tot=0;
    mu[1]=1;
    for(int i=2; i<N; ++i) {
        if(!nop[i]) {
            p[++tot]=i;
            mu[i]=-1;
            // 单个素数为-1
        }
        for(int j=1; j<=tot&&i*p[j]<N; ++j) {
            nop[i*p[j]] = 1;
            if(i%p[j]==0) {
                mu[i*p[j]] = 0;
                //存在两个相同的素数因子,为0
                break;
            }
            mu[i*p[j]] = -mu[i]; // 乘-1
        }
    }
    // 求mu前缀和。
    for(int i=1; i<N; ++i) mu[i]+=mu[i-1];
}
int solve(int n, int m) {
    int res = 0;
    for(int i=1, j; i<=min(n, m); i=j+1) {
        j = min(n/(n/i), m/(m/i));
        // [i, j]分块计算
        res += (mu[j]-mu[i-1])*(n/i)*(m/i);
    }
    return res;
}
int main() {
    int a, b, c, d, k, T;
    scanf("%d", &T);
    init();
    while(T--) {
        scanf("%d%d%d%d%d", &a, &b, &c, &d, &k);
        int res = solve(b/k, d/k);
        res -= solve((a-1)/k, d/k);
        res -= solve(b/k, (c-1)/k);
        res += solve((a-1)/k, (c-1)/k);
        printf("%d\n", res);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值