怎么求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;
}