题目描述
输入描述:
输出描述:
示例1
输入
3
输出
5
分析:
1.这个题其实考的是一个莫比乌斯反演题,但是由于我知识储备不够,没有看出来,题目给的范围可以瞎搞一下,所以下面容斥可以过。
2.转换一下就是一道经典的反演题,参考
AC代码:
容斥:
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;
typedef long long ll;
const int M=1e5+10;
int f[M];
int cal(int x){int num=0;while(x){num+=x%10;x/=10;}return num;
}
int main(){int n;cin>>n;ll ans=0;for(int i=2;i<=n;i++){int m=i,kk=0;for(int j=2;j*j<=n;j++){///唯一分解定理,求其素因子if(m%j==0){f[kk++]=j;while(m%j==0)m/=j;}}if(m>1) f[kk++]=m;int lim=1<<kk,sum=0;for(int j=1;j<lim;j++){///枚举哪些质因子被拿出来了int x=j,su=0,sm=1;for(int k=0;k<kk;k++){///找出哪些素因子被拿出if(x&(1<<k)){su++;sm*=f[k];}}if(su&1) sum+=n/sm-i/sm;///规定,当素因子拿出奇数个,则加上,在(i~n)里存在该质因子数的个数。else sum-=n/sm-i/sm;///当为偶数时,此时之前已经拿出,重复,需减掉。}///sum为不互质的数;///n-i,为总数,原为找寻的for(j=i+1,j<=n;j++)中(i,j)互质的数ans+=(n-i-sum)*cal(i);}ans+=n;///没有枚举1,因为全部会被标记,所以+1cout<<ans<<endl;return 0;
}
莫比乌斯反演:
#include<stdio.h>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int M=1e5+10;
int prime[M],mu[M],f[M];
int cnt;
bool book[M];
void sieve(int N)
{mu[1]=1;for(int i=2; i<=N; i++){if(!book[i])prime[cnt++]=i,mu[i]=-1;for(int j=0; prime[j]<=N/i; j++){book[i*prime[j]]=true;if(i%prime[j]==0)break;mu[i*prime[j]]=-mu[i];}}for(int i = 0; i <= N; i++){int x = i;while(x){f[i]+=x%10;x/=10;}}
}
int main()
{sieve(M - 1);int n;scanf("%d",&n);ll ans=0;for(int i=1; i<=n; i++){if(!mu[i])continue;ll res=0;for(int j=1; j<=n/i; j++)res+=(ll)f[j*i]*(n/i-j+1);//1LL,长整型1,和*1.0一样,改变数据类型用;ans+=mu[i]*res;}printf("%lld\n",ans);return 0;
}