跳到主要内容

筛法求莫比乌斯函数

唯一分解定理: n = i=1spiαi=p1α1p2α2psαsn~=~\prod_{i=1}^{s}p_{i}{}^{\alpha_{i}}\,=\,p_{1}{}^{\alpha_{1}}p_{2}{}^{\alpha_{2}}\cdots p_{s}{}^{\alpha_{s}} 莫比乌斯函数定义: μ(n)={1n=10n 含相同质因子 (1)ss 为 n 的不同质因子的个数 \mu(n)=\left\{\begin{array}{ll} 1 & n=1 \\ 0 & n \text { 含相同质因子 } \\ (-1)^{s} & s \text { 为 } n \text { 的不同质因子的个数 } \end{array}\right. 例如:μ[1,6,10,15]=1,μ[4,8,9,12]=0,μ[2,3,5,7,30]=1\mu[1,6,10,15]=1,\mu[4,8,9,12]=0,\mu[2,3,5,7,30]=-1 筛法求莫比乌斯函数: 若i是质数,μ[i]=1\mu[i]=-1,在线性筛中,每个合数被最小质因子筛去,设pip_imm的最小质因子,则mm通过ipii*p_i筛掉。

  1. 如果ii能被pip_i整除,则ii也包含质因子pip_i,此时μ(m)=0\mu(m)=0
  2. 如果ii不能被pip_i整除,则mmii多一个不同的质因子pip_i,此时μ(m)=μ(m)\mu(m)=-\mu(m),原因如下:
    1. 如果μ(i)=1\mu(i)=-1,则μ(m)=1\mu(m)=1
    2. 如果μ(i)=0\mu(i)=0,则μ(m)=0\mu(m)=0
    3. 如果μ(i)=1\mu(i)=1,则μ(m)=1\mu(m)=-1

代码:

#include <bits/stdc++.h>

using namespace std;

#define endl '\n'
#define debug(x) cout<<"a["<<x<<"]="<<a[x]<<endl;
#define pr(x) cout<<x<<endl;
#define IOS ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)

typedef long long LL;
typedef pair<int, int> PII;
const int INF = 0x3f3f3f3f;
const int N = 1e5 + 10;

int p[N], st[N], cnt;
int mu[N];

//筛法求莫比乌斯函数
void get(int n) {
mu[1]=1;
for(int i=2;i<=n;i++){
if (!st[i]){//质数
p[++cnt]=i;//加入到质数中去
mu[i]=-1;//第一次筛到肯定为-1
}
for(int j=1;i*p[j]<=n;j++){
st[i*p[j]]=true;
if (i%p[j]==0){
mu[i*p[j]]=0;//i*p[j]至少有两个质因子
break;
}else{
mu[i]=-mu[i];
}
}
}

}

int main() {
IOS;
#ifndef ONLINE_JUDGE
freopen("/Users/houyunfei/CLionProjects/MyCppWorkSpace/test.in", "r", stdin);
freopen("/Users/houyunfei/CLionProjects/MyCppWorkSpace/test.out", "w", stdout);
#endif
int n;
cin >> n;
get(n);
for (int i = 1; i <= n; i++)
pr(mu[i])

return 0;
}