莫比乌斯反演0

弃坑

莫比乌斯函数

定义

设函数$mu(n)$为莫比乌斯函数

$$mu =egin{cases}left( -1 ight) ^{k}left( n=p_{1}p_{2}ldots p_{k} ight) \ Oleft( exists P^{2}|n ight) \ 1left( n=1 ight) end{cases}$$

性质

  • $mu(n)$为积性函数
  • $$sum _{d|n}mu left( d ight) =left[ n=1 ight]$$(非常重要!!)

莫比乌斯反演

公式

如果

$gleft( n ight) =sum _{d|n }fleft( d ight)$

那么

$fleft( n ight) =sum _{d|n}mu left( d ight) gleft( dfrac {n}{d} ight)$

证明

$$sum _{d|n}mu left( d ight) gleft( dfrac {n}{d} ight)$$

$$=sum _{d|n}mu left( dfrac {n}{d} ight) gleft( d ight)$$

$$=sum _{d|n}mu left( dfrac {n}{d} ight) sum _{k|d}fleft( k ight)$$

$$=sum _{k|n}sum_{d|{dfrac{n}{k}}}mu(d)f(k) $$

$$=sum _{k|n}[dfrac{n}{k}=1]f(k) $$

$$=f(n)$$

莫比乌斯函数的计算方法

因为$mu(n)$为积性函数

那么可以利用线性筛来计算

#include<cstdio>
#include<cstring>
const int MAXN=1e6+10;
int prime[MAXN],mu[MAXN],vis[MAXN],tot,n;
void Euler()
{
    vis[1]=1;mu[1]=1; 
    for(int i=2;i<=n;i++)
    {
        if(!vis[i])    prime[++tot]=i,mu[i]=-1;//只有一个质因子 
        for(int j=1;i*prime[j]<=n&&j<=tot;j++)
        {
            vis[ i*prime[j] ]=1;
            if(i%prime[j]==0)//i中包含prime[j] 
            {
                mu[ i*prime[j] ]=0;//乘起来之后肯定包含prime[j]^2 
                break; 
            }
            else mu[ i*prime[j] ]=-mu[i];//多了一个质因子 
        }
    }
}
int main()
{
    printf("Please input number:
");
    scanf("%d",&n);
    Euler();
    printf("%d",mu[n]);
    return 0;
}
原文地址:https://www.cnblogs.com/zwfymqz/p/8215540.html