1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| #include <cstdio> #include <cstring> #include <cmath> using namespace std; #define ll long long const ll mod=1e9+7; const ll inv2=(mod+1)>>1; inline ll Add(ll x,ll y){x+=y; return (x<mod)?x:x-mod;} inline ll Dec(ll x,ll y){x-=y; return (x<0)?x+mod:x;} inline ll Mul(ll x,ll y){return x*y%mod;} inline ll Pow(ll x,ll y) { y%=(mod-1); ll ans=1; for(;y;y>>=1,x=x*x%mod) if(y&1) ans=ans*x%mod; return ans; } const int N=1000000; ll n,m,Sqr,pri[N],sp[N],id1[N],id2[N],w[N]; ll h[N],g[N]; bool vis[N]; int tot; void init_prime(int n) { vis[1]=1; for(int i=2;i<=n;i++) { if(!vis[i]) {pri[++tot]=i; sp[tot]=(sp[tot-1]+i)%mod;} for(int j=1;j<=tot&&1ll*i*pri[j]<=n;j++) { vis[i*pri[j]]=1; if(i%pri[j]==0) break; } } }
ll S(ll n,int j) { if(n<=1||pri[j]>n) return 0; ll t=(n<=Sqr)?id1[n]:id2[::n/n]; ll ans=(mod+(g[t]-sp[j-1])-(h[t]-(j-1))%mod)%mod; if(j==1) ans+=2; for(int k=j;k<=tot&&pri[k]*pri[k]<=n;k++) { ll tmp=pri[k]; for(int q=1;tmp*pri[k]<=n;q++,tmp*=pri[k]) ans=Add(ans,Add(pri[k]^(q+1),Mul(pri[k]^q,S(n/tmp,k+1)))); } return ans; }
int main() { scanf("%lld",&n); Sqr=sqrt(n); init_prime(Sqr); for(ll i=1,j;i<=n;i=j+1) { j=n/(n/i); w[++m]=n/i; h[m]=(w[m]-1)%mod; g[m]=(w[m]%mod)*((w[m]+1)%mod)%mod*inv2%mod-1; if(w[m]<=Sqr) id1[w[m]]=m; else id2[j]=m; } for(int i=1;i<=tot;i++) { ll k=pri[i]*pri[i]; for(int j=1;j<=m&&k<=w[j];j++) { int t=(w[j]/pri[i]<=Sqr)?id1[w[j]/pri[i]]:id2[n/(w[j]/pri[i])]; h[j]=Add(h[j],(mod-(h[t]-(i-1)%mod))%mod); g[j]=Add(g[j],mod-1ll*pri[i]*(g[t]-sp[i-1]+mod)%mod); } } printf("%lld",(S(n,1)+1)%mod); return 0; }
|