莫比乌斯反演(模板)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yz467796454/article/details/82020166

太难了!看了这个博客:莫比乌斯反演详解

 

构造是重点,现在看这题:

 

构造方法和上面的讲解中的构造是基本一致的

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
using namespace std;
typedef long long ll;
const int maxn=1e7+7;

ll pri[maxn],pri_num;
ll mu[maxn];//莫比乌斯函数值
bool vis[maxn];
void mobius(int N)  //筛法求莫比乌斯函数
{
    pri_num = 0;//素数个数
    memset(vis, false, sizeof(vis));
    vis[1] = true;
    mu[1] = 1;
    for(int i = 2; i <=N; i++)
    {
        if(!vis[i])
        {
            pri[pri_num++] = i;
            mu[i] = -1;
        }
        for(int j=0; j<pri_num && i*pri[j]<N ; j++)
        {
            vis[i*pri[j]]=true;//标记非素数
            //eg:i=3,i%2,mu[3*2]=-mu[3]=1;----;i=6,i%5,mu[6*5]=-mu[6]=-1;
            if(i%pri[j])mu[i*pri[j]] = -mu[i];
            else
            {
                mu[i*pri[j]] = 0;
                break;
            }
 
        }
    }
}
int main(){
	mobius(maxn);
	int n;
	while(~scanf("%d",&n)){
		ll ans=0;
		for(int i=0;pri[i]<=n;i++){
			for(int j=1;j<=n/pri[i];j++){
				ll x=n/pri[i]/j;
				ans+=mu[j]*x*x;
			}
		}
		printf("%lld\n",ans);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/yz467796454/article/details/82020166