莫比乌斯函数

怎么求1 ~ n 的莫比乌斯函数

莫比乌斯函数

莫比乌斯函数的定义

μ ( n ) = { 1 若 n = 1 0 若 n 含有相同的质因子 ( − 1 ) k 若 n 是 k 个不同质数的乘积 \mu(n) = \begin{cases} 1 & \text{若 } n = 1 \\ 0 & \text{若 } n \text{ 含有相同的质因子} \\ (-1)^k & \text{若 } n \text{ 是 } k \text{ 个不同质数的乘积} \\ \end{cases} μ(n)=⎩ ⎨ ⎧10(−1)k若 n=1若 n 含有相同的质因子若 n 是 k 个不同质数的乘积

如何求 1 ∼ n 1 \sim n 1∼n的莫比乌斯函数

对于 2 ∼ n 2 \sim n 2∼n的每一个数 i i i

  • 如果 i i i是质数,那么它就只有一个质因子,也就是它本身,所以 μ ( i ) = − 1 \mu(i)=-1 μ(i)=−1
  • 如果 i i i合数,设 p p p为确定 i i i的最小质因子,也就是说,可以将 i i i表示为 i = p ∗ k i=p*k i=p∗k,
    • 如果 k   m o d   p = 0 k \bmod p =0 kmodp=0,那么 k k k就含有和 i i i一样的所有质因子,所以在 i i i中就有相同质因子 p p p了,所以此时
      μ ( i ) = 0 \mu(i)=0 μ(i)=0

    • 如果 k   m o d   p ≠ 0 k \bmod p \ne0 kmodp=0,那么就相当于 i i i比 k k k多了一个质数 p p p来构成,并且 p p p的指数为1,所以这个时候就需要看 μ ( k ) \mu(k) μ(k)

      • 如果 μ ( k ) = 0 \mu(k)=0 μ(k)=0,那么 μ ( i ) = 0 \mu(i)=0 μ(i)=0,因为 k k k有相同的质因子,所以 i i i也有相同的质因子。
      • 如果 μ ( k ) = 1 \mu(k)=1 μ(k)=1,那么 μ ( i ) = − 1 \mu(i)=-1 μ(i)=−1,因为 i i i中质因子的个数比 k k k多一个 p p p,所以需要让 μ ( k ) \mu(k) μ(k)乘上一个 − 1 -1 −1。
      • 如果 μ ( k ) = − 1 \mu(k)=-1 μ(k)=−1,那么 μ ( i ) = 1 \mu(i)=1 μ(i)=1,同上。

      所以我们发现,当 μ ( k ) ≠ 0 \mu(k) \ne 0 μ(k)=0时, μ ( k ) \mu(k) μ(k)和 μ ( i ) \mu(i) μ(i)的符号都是相反的,并且的相反数也是0,所以可以写成:
      μ ( i ) = − μ ( k ) \mu(i)=-\mu(k) μ(i)=−μ(k)

参考代码

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
using ll =long long ;

const int N=1e6;
int p[N],v[N],mu[N];
int cnt;


void get_mu(int n){
	mu[1]=1;
	for(int i=2;i<=n;i++){
		if(!v[i]){
			v[i]=i;
			mu[i]=-1;
			p[++cnt]=i;
		}
		for(int j=1;j<=cnt;j++){
			if(p[j]>i||p[j]>n/i)break;
			int m=i*p[j];
			v[m]=p[j];
			if(i%p[j]==0){
				mu[m]=0;
			}
			else{
				mu[m]=-mu[i];
			}
		}
	}
}
int main(){
	int n;
	cin>>n;
	get_mu(n);
	for(int i=1;i<=n;i++)
		cout<<mu[i]<<' ';
	cout<<endl;
}