#include<bits/stdc++.h> #define LL long long using namespace std; const int maxn=1e7+10; bool vis[maxn]; int prime[maxn]; int mu[maxn]; int sum1[maxn]; int sum2[maxn]; int tot=0; void get_mu()// mo bi su si han shu { mu[1]=1; vis[1]=1; for(int i=2;i<maxn;i++) // prime = 0; other = 1; { if(!vis[i]){ prime[++tot]=i; mu[i]=-1;} for(int j=1;j<=tot&& prime[j]*i<maxn;j++) { vis[prime[j]*i]=1; if(i%prime[j]==0)break; mu[i*prime[j]]=-mu[i]; } } for(int i=1;i<=tot;i++) { for(int j=prime[i];j<maxn;j+=prime[i]) { sum1[j]+=mu[j/prime[i]]; } } //for(int i=1;i<maxn;i++) sum2[i]=sum2[i-1]+sum1[i]; } int main() { get_mu(); int n; cin>>n; LL ans=0; for(int i=1;i<=n;i++) { ans+=1LL*(n/i)*(n/i)*sum1[i]; } cout<<ans<<endl; }
整除分块 (看起来更麻烦)
#include<bits/stdc++.h> #define LL long long using namespace std; const int maxn=1e7+10; bool vis[maxn]; int prime[maxn]; int mu[maxn]; int sum1[maxn]; int sum2[maxn]; int tot=0; void get_mu()// mo bi su si han shu { mu[1]=1; vis[1]=1; for(int i=2;i<maxn;i++) // prime = 0; other = 1; { if(!vis[i]){ prime[++tot]=i; mu[i]=-1;} for(int j=1;j<=tot&& prime[j]*i<maxn;j++) { vis[prime[j]*i]=1; if(i%prime[j]==0)break; mu[i*prime[j]]=-mu[i]; } } for(int i=1;i<=tot;i++) { for(int j=prime[i];j<maxn;j+=prime[i]) { sum1[j]+=mu[j/prime[i]]; } } for(int i=1;i<maxn;i++) sum2[i]=sum2[i-1]+sum1[i]; } int main() { get_mu(); int n; cin>>n; LL ans=0; //for(int i=1;i<=n;i++) ans+=1LL*(n/i)*(n/i)*sum1[i]; for(int l=1,r;l<=n;l=r+1) { r=n/(n/l); // l-r 区间相同值 区间值n/l ans+=1LL*(n/l)*(n/l)*(sum2[r]-sum2[l-1]); } cout<<ans<<endl; }