题意
,答案对
取膜
部分分
,
首先发现
然后反演掉最后的
就可以
对于
,就可以直接做了
但是这个做法常数很小,所以加一些常数优化,就可以通过
#include<bits/stdc++.h>
using namespace std;
#define int unsigned int//无符号整型速度很快
const int maxn=1e7+5;
inline int read(){
char c=getchar();int t=0,f=1;
while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){t=(t<<3)+(t<<1)+(c^48);c=getchar();}
return t*f;
}
int mu[maxn],p[maxn],vis[maxn],n,cnt;
void get(){
mu[1]=1;
for(int i=2;i<=n;i++){
if(!vis[i]){
p[++cnt]=i;mu[i]=-1;
}
for(int j=1;i*p[j]<=n&&j<=cnt;j++){
vis[i*p[j]]=1;
mu[i*p[j]]=mu[i]*mu[p[j]];
if(i%p[j]==0){
mu[i*p[j]]=0;
break;
}
}
}
}
int alfa[maxn];
signed main(){
//freopen("T2.in","r",stdin);
//freopen("T2.out","w",stdout);
n=read();
get();
for(int i=n;i>=1;i--){
int tmp=n/i;
if(i*2<=n)//这里是常数优化
alfa[i]=alfa[i*2];
for(int j=1;j<=tmp;j+=2)//注意这里的步长
alfa[i]=alfa[i]+mu[i*j];
}
int ans=0;
for(int i=1;i<=n;i++){
int tmp=mu[i]*alfa[i]*alfa[i];
ans=ans+tmp;
}
printf("%u\n",ans);
return 0;
}