莫比乌斯反演入门

一、引入
假设有两个函数F(n),f(d),且d∈{x| x|n(即n被d整除)}
并有以下关系:F(n)等于所有f(d)之和。

在这里插入图片描述

二、推导【μ(d)】
由公式得到:

F(1)=f(1)
F(2)=f(1)+f(2)
F(3)=f(1)+ f(3)
F(4)=f(1)+f(2)+f(4)
F(5)=f(1)+f(5)
F(6)=f(1)+f(2)+f(3)+f(6)

进而:

f(1)=F(1)
f(2)=F(2)-f(1)=F(2)-F(1)
f(3)=F(3)-F(1)
f(4)=F(4)-f(2)-f(1)=F(4)-F(2)
f(5)=F(5)-F(1)
f(6)=F(6)-F(3)-F(2)+F(1)

每一个f(n)都由它所有的因子d∈{x| x|n(即n被d整除)}的F(d)乘上一个系数μ(d),μ(d)的值只可能是0,-1,1

根据观察得出规律:
若d为k个互质互异因子的乘积,则μ(d)=(-1)^k;
除1外不能由几个互质且互异的正整数相乘得到的数d,则则μ(d)=0;
其他情况,μ(1)=1.

即:
莫比乌斯反演入门_第1张图片

性质:
莫比乌斯反演入门_第2张图片

三、定义
两种形式:
1.由:
莫比乌斯反演入门_第3张图片
得:
莫比乌斯反演入门_第4张图片
2.由:
在这里插入图片描述
得:
莫比乌斯反演入门_第5张图片

四、求莫比乌斯函数代码

#include 
using namespace std;
const int maxn=19260817;
int n;
int prime[maxn];///记录素数 
int mobius[maxn];///记录莫比乌斯函数值 
bool vis[maxn];
int cnt=0;///记录素数个数 
void make_mobius(int m)
{
    memset(vis,0,sizeof(vis));
    mobius[1]=1;
    for(int i=2;i<=m;i++)
    {
        if(!vis[i]){
            prime[++cnt]=i;
            mobius[i]=-1;///素数的μ()为-1,
            ///只有其本身一个互异互质因子 
        }
        for(int j=1;j<=cnt&&i*prime[j]<=m;j++)
        {
            vis[i*prime[j]]=1;///筛素数
            if(i%prime[j]==0){
                mobius[i*prime[j]]=0;break; 
            ///设x=i*prime[j]很明显它的两个因子i与prime[j]不互质 
            }
            mobius[i*prime[j]]=-mobius[i];
        ///i*prime[j]比i多了一个因子 
        }
    }
}
int main()
{
    cin>>n;
    make_mobius(n);
    for(int i=1;i<=n;i++)
    {
        cout<<mobius[i]<<' ';
        if(i%10==0)
            putchar('\n');
    }
    return 0;
} 

你可能感兴趣的:(数论,模板)