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 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
| #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<queue> #include<map> #include<stack> #include<set> #include<bitset> #include<cmath> #include<assert.h> #define inc(i,l,r) for(int i=l;i<=r;i++) #define dec(i,l,r) for(int i=l;i>=r;i--) #define link(x) for(edge *j=h[x];j;j=j->next) #define mem(a) memset(a,0,sizeof(a)) #define ll long long #define eps 1e-8 #define succ(x) (1<<x) #define lowbit(x) (x&(-x)) #define sqr(x) ((x)*(x)) #define mid (x+y>>1) #define NM 2000005 #define nm 128 #define pi 3.1415926535897931 using namespace std; const ll inf=1e9+7; ll read(){ ll x=0,f=1;char ch=getchar(); while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} while(isdigit(ch))x=x*10+ch-'0',ch=getchar(); return f*x; }
int tot,m; ll w[NM],pre[NM],f[NM],h[NM],prime[NM],n; bool v[NM];
inline void reduce(ll&x){x+=x>>63&inf;} inline int id(ll x){return x<=m/2?m-x+1:n/x;}
void init(){ m=sqrt(n); inc(i,2,m)if(!v[i]){ prime[++tot]=i; for(int j=i<<1;j<=m;j+=i)v[j]++; } inc(i,1,tot)pre[i]=(pre[i-1]+prime[i])%inf; inc(i,1,m)w[i]=n/i; while(w[m]>1)w[m+1]=w[m]-1,m++; }
ll S(ll n,int m){ if(n<prime[m])return 0; ll ans=(f[id(n)]-pre[m-1]+inf)%inf; for(int i=m;i<=tot&&prime[i]*prime[i]<=n;i++){ ll t=prime[i]; for(int j=1;t*prime[i]<=n;t*=prime[i],j++) reduce(ans+=(prime[i]^j)*S(n/t,i+1)%inf-inf), reduce(ans+=(prime[i]^(j+1))-inf); } return ans; }
int main(){ n=read(); init(); inc(i,1,m)f[i]=w[i]%inf*((w[i]+1)%inf)%inf*(inf+1)/2%inf-1,h[i]=(w[i]-1)%inf; inc(j,1,tot){ inc(i,1,m)if(w[i]>=prime[j]*prime[j]){ int k=id(w[i]/prime[j]); reduce(f[i]-=prime[j]*(f[k]-pre[j-1]+inf)%inf); reduce(h[i]-=h[k]-j+1); }else break; } inc(i,1,m-1)f[i]+=2; inc(i,1,m)reduce(f[i]-=h[i]); inc(i,1,tot)pre[i]=(pre[i-1]+(prime[i]^1))%inf; printf("%lld\n",S(n,1)+1); return 0; }
|