莫比乌斯反演总结

莫比乌斯反演


1. 定义

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

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

那么有如下结论:

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

其中:
( 1 ) d = 1 , μ ( d ) = 1
( 2 ) d = p 1 p 2 p 3 p 4 . . . p k , d k μ ( d ) = ( 1 ) k
( 3 ) μ ( d ) = 0

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

性质1:

d | n n μ ( d ) = { 1 n = 1 0 , n > 1

证明:
n=1时显然成立;
n>1时:
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 | n 1 d | n , d μ ( d ) ,
那么易知
d | n n μ ( d ) = d | n 1 n 1 μ ( d )

μ ( d )
d | n 1 n 1 = i k C ( k , i ) ( 1 ) i

由二项式定理:

( a + b ) n = i = 0 n C ( n , i ) a i b n i

a = 1 , b = 1 ,
d | n 1 n 1 = ( 1 + 1 ) n = 0

性质2:

d | n n μ ( d ) d = Φ ( n ) 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 | n d , d | n , d = k n d , d = k n d , d | n d , d = 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 | d n μ ( d n ) F ( d )

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

n | d n μ ( d n ) F ( d ) = k = 1 + μ ( k ) F ( n k ) = k = 1 + μ ( k ) n k | d f ( d )
= n | d f ( d ) k | n d μ ( k ) = f ( n ) d = n k | n d μ ( k ) = 1

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

1.一道简单例题:
i 1 n , j 1 m i , j

i n j m [ g c d ( i , j ) = 1 ]

f ( x ) n , m g c d = x , F ( x ) = x | d f ( d x )
F ( x ) n , m x | g c d ,

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

f ( 1 ) = d = 1 m i n ( n , m ) μ ( d ) F ( d )
易知 F ( d ) = n d m d , g c d d
那么 f ( 1 ) = d = 1 m i n ( n , m ) μ ( d ) n d m d

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

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
= d = 1 m i n ( n k , m k ) μ ( d ) n k d m k d (可以理解为枚举了 d k ) , n = n k , m = m k
= d = 1 m i n ( n , m ) n d m d μ ( d )

然后还可以对除法进行分块,并求出 μ ( d ) 的前缀和,即可达到每次 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

猜你喜欢

转载自blog.csdn.net/element_hero/article/details/79843058