# 「算法笔记」Min_25 筛

//LOJ 6053 简单的函数 f(p^c)=p xor c
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+5,mod=1e9+7;
int n,s,tot,val[N],id1[N],id2[N],x,cnt,p[N],sum[N],g[N],h[N],inv2=500000004;
bool vis[N];
int id(int x){
return x<=s?id1[x]:id2[n/x];
}
int S(int x,int y){
if(x<=1||p[y]>x) return 0;
int ans=((g[id(x)]-h[id(x)]-(sum[y-1]-(y-1)))%mod+mod)%mod;
if(y==1) ans+=2;
for(int i=y;i<=cnt&&p[i]*p[i]<=x;i++){
int p1=p[i],p2=p[i]*p[i];
for(int e=1;p2<=x;e++,p1=p2,p2*=p[i])
ans=(ans+((p[i]^e)*S(x/p1,i+1)%mod+(p[i]^(e+1))%mod)%mod)%mod;
}
return ans;
}
signed main(){
scanf("%lld",&n),s=sqrt(n);
vis[0]=vis[1]=1;
for(int i=2;i<=s;i++){
if(!vis[i]) p[++cnt]=i,sum[cnt]=(sum[cnt-1]+i)%mod;
for(int j=1;j<=cnt&&i*p[j]<=s;j++){
vis[i*p[j]]=1;
if(i%p[j]==0) break;
}
}
for(int l=1,r=0;l<=n;l=r+1){
r=n/(n/l),x=n/l,val[++tot]=x;
if(x<=s) id1[x]=tot;
else id2[n/x]=tot;
x%=mod,g[tot]=(2+x)*(x-1)%mod*inv2%mod,h[tot]=(x-1)%mod;
}
for(int j=1;j<=cnt;j++)
for(int i=1;i<=tot&&p[j]*p[j]<=val[i];i++){
g[i]=(g[i]-p[j]*(g[id(val[i]/p[j])]-sum[j-1])%mod+mod)%mod;
h[i]=(h[i]-(h[id(val[i]/p[j])]-(j-1))%mod+mod)%mod;
}
printf("%lld\n",S(n,1)+1);
return 0;
}
posted @ 2021-03-01 17:11  maoyiting  阅读(160)  评论(0编辑  收藏  举报