莫比乌斯反演总结

本文详细介绍了莫比乌斯反演的概念、性质、筛法及其在计算问题中的应用。通过实例展示了如何使用莫比乌斯反演解决求解互质对数的问题,并给出了相关题目及解题思路,强调了掌握推导、变换技巧和莫比乌斯函数性质的重要性。

莫比乌斯反演


1. 定义

对于一个定义在非负整数上的函数 f(n) f ( n ) ,定义函数 F(n) F ( n )

F(n)=d|nf(d) F ( n ) = ∑ d | n f ( d )

那么有如下结论:

f(n)=d|nμ(d)F(nd) f ( n ) = ∑ d | n μ ( d ) F ( n d )

其中:
(1)d=1,μ(d)=1 ( 1 ) 若 d = 1 , 则 μ ( d ) = 1
(2)d=p1p2p3p4...pk,dkμ(d)=(1)k ( 2 ) 若 d = p 1 p 2 p 3 p 4 . . . p k , 即 d 有 k 个 互 异 的 质 因 子 μ ( d ) = ( − 1 ) k
(3)μ(d)=0 ( 3 ) 其 他 情 况 下 μ ( d ) = 0

2.莫比乌斯函数的性质&证明

性质1:

d|nnμ(d)={10,n=1n>1 ∑ d | n n μ ( d ) = { 1 , 若 n = 1 0 , 若 n > 1

证明:
n=1时显然成立;
n>1时:
n=pa11pa22pa33...pakk,n1=p1p2p3...pk 设 n = p 1 a 1 p 2 a 2 p 3 a 3 . . . p k a k , n 1 = p 1 p 2 p 3 . . . p k
d,d|n1d|n,dμ(d), 设 d , d | n 1 所 以 d | n , 若 d 包 含 多 个 相 同 质 因 子 , 则 μ ( d ) 无 贡 献 , 反 之 有 贡 献
那么易知
d|nnμ(d)=d|n1n1μ(d) ∑ d | n n μ ( d ) = ∑ d ′ | n 1 n 1 μ ( d ′ )

μ(d) 所 以 μ ( d ) 的 值 与 取 的 质 因 子 个 数 有 关 , 即
d|n1n1=ikC(k,i)(1)i ∑ d | n 1 n 1 = ∑ i k C ( k , i ) ∗ ( − 1 ) i

由二项式定理:

(a+b)n=i=0nC(n,i)aibni ( a + b ) n = ∑ i = 0 n C ( n , i ) a i b n − i

a=1,b=1, a = − 1 , b = 1 , 则
d|n1n1=(1+1)n=0 ∑ d | n 1 n 1 = ( − 1 + 1 ) n = 0 证 毕

性质2:

d|nnμ(d)d=Φ(n)n ∑ d | n n μ ( d ) d = Φ ( n ) n

莫比乌斯反演定理的证明:

=d|nnμ(d)F(nd)=d|nnμ(d)d|ndndf(d)=d|nnf(d)d|ndndμ(d)=f(n) 左 边 = ∑ d | n n μ ( d ) F ( n d ) = ∑ d | n n μ ( d ) ∑ d ′ | n d n d f ( d ′ ) = ∑ d ′ | n n f ( d ′ ) ∑ d | n d ′ n d ′ μ ( d ) = f ( n )

最后两步的解释:
我们枚举d’,因为 d|nd,d|n,d=knd,d=knd,d|nd,d=n d ′ | n d , 所 以 d ′ | n , 令 d ′ = k n d , 那 么 d = k n d ′ , 即 d | n d ′ , 然 后 当 且 仅 当 d ′ = n 时
ndd|ndμ(d)=1,f(n) ∑ d | n d ′ n d ′ μ ( d ) = 1 , 最 后 结 果 为 f ( n )

3.莫比乌斯函数的筛法

线性筛法:

int pri[N];int cnt=0;
bool vis[N];
int mu[N];
inline void prepare()//线性筛法求 mu(d)
{
    vis[1]=1;
    for(register int i=2;i<=n;i++)
    {
        if(!vis[i]) {pri[++cnt]=u;mu[i]=-1;}
        for(register int j=1;j<=cnt&&((1ll*pri[j]*i)<=n);j++)
        {
            vis[pri[j]*i]=1;
            if(i%pri[j]==0) {mu[i*pri[j]]=0;break;}//此时有两个相同因子
            mu[i*pri[j]]=-mu[i];//新加一个相异质数;
        }
    }
    return ;
}

4.应用

注:以下除法未说明均为向下取整。

其实莫比乌斯反演还有另一种描述:

f(n)=n|dnμ(dn)F(d) f ( n ) = ∑ n | d n μ ( d n ) F ( d )

证明类似:
首先知道若 nk|d, n k | d , 那么 n|d,k|d n | d , k | d

nn|dμ(dn)F(d)=+k=1μ(k)F(nk)=+k=1μ(k)nk|df(d) ∑ n | d n μ ( d n ) F ( d ) = ∑ k = 1 + ∞ μ ( k ) F ( n k ) = ∑ k = 1 + ∞ μ ( k ) ∑ n k | d ′ f ( d ′ )
=n|df(d)k|ndμ(k)=f(n)d=nk|ndμ(k)=1 = ∑ n | d f ( d ) ∑ k | n d μ ( k ) = f ( n ) 当 且 仅 当 d = n 时 ∑ k | n d μ ( k ) = 1

一般都用这种
担心d会无限增大?F(d)这时就会没贡献了

1.一道简单例题:
i1n,j1mi,j 求 i 从 1 到 n , j 从 1 到 m 的 i , j 互 质 的 对 数

injm[gcd(i,j)=1] 即 为 ∑ i n ∑ j m [ g c d ( i , j ) = 1 ]

f(x)n,mgcd=x,F(x)=x|df(dx) 那 么 就 设 f ( x ) 为 n , m 内 g c d = x 的 对 数 , F ( x ) = ∑ x | d f ( d x )
F(x)n,mx|gcd, 那 么 推 知 F ( x ) 表 示 n , m 内 x | g c d 的 对 数 ,

现在要求 f(1) f ( 1 ) ,套用公式就是:
f(1)=min(n,m)1|dμ(d1)F(d) f ( 1 ) = ∑ 1 | d m i n ( n , m ) μ ( d 1 ) F ( d )

f(1)=min(n,m)d=1μ(d)F(d) f ( 1 ) = ∑ d = 1 m i n ( n , m ) μ ( d ) F ( d )
易知 F(d)=ndmd,gcdd F ( d ) = n d ∗ m d , 即 为 g c d 是 d 的 倍 数 的 对 数
那么 f(1)=min(n,m)d=1μ(d)ndmd f ( 1 ) = ∑ d = 1 m i n ( n , m ) μ ( d ) n d ∗ m d

这样我们其实也可以轻松求出 gcd=k g c d = k 的对数,因为 n,m n , m gcd=k g c d = k 的数的对数即为 nd,md, n d , m d 中 , gcd=1 g c d = 1 的数的对数。
所以就是:

f(k)=min(n,m)k|dμ(dk)F(d)=min(n,m)k|dμ(dk)ndmd f ( k ) = ∑ k | d m i n ( n , m ) μ ( d k ) F ( d ) = ∑ k | d m i n ( n , m ) μ ( d k ) n d ∗ m d
=min(nk,mk)d=1μ(d)nkdmkd = ∑ d = 1 m i n ( n k , m k ) μ ( d ) n k d ∗ m k d (可以理解为枚举了 dk),n=nk,m=mk d k ) , 令 n ′ = n k , m ′ = m k
=min(n,m)d=1ndmdμ(d) = ∑ d = 1 m i n ( n ′ , m ′ ) n ′ d ∗ m ′ d ∗ μ ( d )

然后还可以对除法进行分块,并求出 μ(d) μ ( d ) 的前缀和,即可达到每次 O(n) O ( n ) 的回答
虽然预处理有O(n)

贴个代码 LupguP2522 [HAOI2011]Problem b

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cmath>
using namespace std;
inline int read()
{
    int x=0;char ch=getchar();int t=1;
    for(;ch>'9'||ch<'0';ch=getchar()) if(ch=='-') t=-1;
    for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+(ch-48);
    return x*t;
}
const int N=5e4+10;
int mu[N];
typedef long long ll;
int pri[N];int cnt;bool vis[N];
inline void prepara()
{
    mu[1]=1;vis[1]=1;
    for(register int i=2;i<=N;i++)
    {
        if(!vis[i]) {pri[++cnt]=i;mu[i]=-1;}
        for(register int j=1;j<=cnt&&(1ll*pri[j]*i<N);j++)
        {
            register int x=i*pri[j];
            vis[x]=1;
            if(i%pri[j]==0) {mu[x]=0;break;}
            mu[x]=-mu[i];
        }
    }
    for(register int i=1;i<N;++i) mu[i]+=mu[i-1];
}
inline ll calc(int a,int b,int c)
{
    if(a>b) swap(a,b);
    if(a==0) return 0;
    a/=c;b/=c;
    register ll res=0;
    register int l,r;
    for(l=1;l<=a;l=r+1)
    {
        r=min(a/(a/l),b/(b/l));
        if(r>a) r=a;
        res+=1ll*(mu[r]-mu[l-1])*(a/l)*(b/l);
    }
    return res;
}
int main()
{
    prepara();
    int T=read();
    while(T--)
    {
        register int a=read(),b=read(),c=read(),d=read(),e=read();
        if(e==0) {puts("0");continue;}
        register ll ans1=calc(b,d,e)-calc(a-1,d,e);
        register ll ans2=calc(b,c-1,e)-calc(a-1,c-1,e);
        //这题还要容斥一波
        printf("%lld\n",ans1-ans2);
    }
}

2.再来几道题

LuoguP2257-YY的GCD
题解

LuoguP3327 约数个数和
题解

LuoguP1829Crash的数字表格
题解

3.小结:
由上面几道题可以看出:

常用套路:
○1.过硬的推式子能力,灵活变更枚举数的顺序
○2.根据式子列出相关函数并利用莫比乌斯反演公式进行求解
○3.利用莫比乌斯函数的性质对式子进行化简,变形

THE END

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值