题目大意
定义一个积性函数F。
若p为质数,
F(pd)=pd−[d mod p!=0]
求F的前缀和。
做法
令
G=F∗μ
,那么G也是一个积性函数。
那么容易得到
G(pd)=pd−[d mod p!=0]−pd−1−[(d−1) mod p!=0]
d=1时G(p)=0。
所以G不为0,则必须每个质因子指数均>=2。
然后莫比乌斯反演得到
F(n)=∑d|nG(d)
则
∑ni=1F(i)=∑ni=1∑d|iG(d)
即答案为
∑nd=1G(d)∗⌊ni⌋
枚举出所有质因子指数均>=2的d计算即可。
#include<cstdio>
#include<algorithm>
#include<cmath>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
typedef long long ll;
const int maxn=10000000+10;
int pri[maxn],id[maxn],f[maxn],g[maxn],h[maxn],L[maxn],sta[100][2];
//ll mi[maxn*3],G[maxn*3];
bool bz[maxn];
int i,j,k,l,m,tot,top,cnt;
ll n,N,t,ans;
void prepare(){
N=floor(sqrt(n));
fo(i,2,N){
if (!bz[i]){
pri[++top]=i;
id[i]=top;
f[i]=h[i]=i;
g[i]=1;
}
fo(j,1,top){
if ((ll)i*pri[j]>N) break;
bz[i*pri[j]]=1;
f[i*pri[j]]=pri[j];
if (i%pri[j]==0){
g[i*pri[j]]=g[i]+1;
h[i*pri[j]]=h[i]*pri[j];
break;
}
g[i*pri[j]]=1;
h[i*pri[j]]=pri[j];
}
}
/*fo(i,1,top){
L[i]=++tot;
mi[tot]=t=1;
G[tot]=0;
j=0;
while (t<=(ll)n/pri[i]){
j++;
t*=pri[i];
mi[++tot]=t;
G[tot]=mi[tot-(j%pri[i]!=0)]-mi[tot-1-((j-1)%pri[i]!=0)];
}
}*/
}
/*ll G(int p,int c){
ll t=mi[L[p]+c-(c%pri[p]!=0)];
t-=mi[L[p]+c-1-((c-1)%pri[p]!=0)];
return t;
}*/
void dfs(ll x,ll y,ll z){
if (!z) return;
ll p=pri[x];
if (x==top+1||y>n/p/p){
ans+=n/y*z;
return;
}
dfs(x+1,y,z);
ll i=2,j,m=n/y;
ll t=p,l=1,r;
m/=t;
while (m>=p){
t*=p;
r=l;
if ((i-1)%p!=0) r*=p;
if (i%p==0) r*=p;
dfs(x+1,y*t,z*(r-l));
l=r;
i++;
m/=p;
}
}
/*void dg(int x,ll y,ll z,ll m){
if (!z) return;
ll t;
int p=sta[x][0],c=sta[x][1];
if (x==cnt+1){
ans+=n/y*z;
return;
}
t=mi[L[p]+2*c];
dg(x+1,y*t,z*G[L[p]+2*c],m);
if (m>=pri[p]){
t*=pri[p];
dg(x+1,y*t,z*G[L[p]+2*c+1],m/pri[p]);
}
}
void work(int x){
cnt=0;
while (x>1){
cnt++;
sta[cnt][0]=id[f[x]];
sta[cnt][1]=g[x];
x/=h[x];
}
dg(1,1,1,(ll)n/x/x);
}*/
int main(){
scanf("%lld",&n);
prepare();
dfs(1,1,1);
//fo(i,1,N) work(i);
printf("%lld\n",ans);
}