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
|
#include <cstring> #include <algorithm> #include <cstdio> #include <cmath>
using namespace std;
typedef long long ll;
const int maxn = 1000010; const int mod = 1e9+7;
ll n;
ll val[maxn]; int f[maxn], g[maxn], h[maxn], mx_p[maxn];
int p[maxn], isnp[maxn], cnt, tot, sqr; int in1[maxn], in2[maxn], s1[maxn], s2[maxn];
inline int (const int &x) { if (x >= mod) return x-mod; if (x < 0) return x+mod; return x; }
int getin(ll x) { if (x >= sqr) { if (!in1[n/x]) in1[n/x] = ++ tot; return in1[n/x]; } else { if (!in2[x]) in2[x] = ++ tot; return in2[x]; } }
ll calp(ll n) { if (n == 1) return 0; return mo(f[getin(n)]-g[getin(n)]+2); }
ll calh(int n, int i) { if (val[n] == 1) return 0; if (val[n] < p[i-1]) return mo(calp(val[n])-s1[mx_p[val[n]]]); else return mo(calp(val[n])-s1[i-1]); }
int main() { isnp[1] = 1; for (int i = 2; i <= 1000000; i++) { if (!isnp[i]) {p[++ cnt] = i; mx_p[i] = cnt;} for (int j = 1; j <= cnt && p[j]*i <= 1000000; j++) { isnp[i*p[j]] = 1; if (i % p[j] == 0) break; } } for (int i = 2; i <= 1000000; i++) if (!mx_p[i]) mx_p[i] = mx_p[i-1]; scanf("%lld", &n); sqr = int(sqrt(n)); for (ll i = 1; i <= n; i = n/(n/i)+1) { val[getin(n/i)] = n/i; } for (int i = 1; i <= tot; i++) {f[i] = (1LL*(val[i]%mod)*(val[i]%mod+1)%mod*((mod+1)/2)%mod-1)%mod; g[i] = mo(val[i]%mod-1);} for (int i = 1; i <= cnt; i++) s1[i] = mo(s1[i-1] + (p[i] ^ 1)); for (int i = 1; i <= cnt; i++) s2[i] = mo(s2[i-1] + p[i]); for (int i = 1; i <= cnt && 1ll*p[i]*p[i] <= n; i++) { for (int j = 1; j <= tot && val[j] >= 1ll*p[i]*p[i]; j++) { f[j] = mo(f[j]-1LL*p[i]*mo(f[getin(val[j]/p[i])]-s2[i-1])%mod); g[j] = mo(g[j]-mo(g[getin(val[j]/p[i])]-(i-1))); } } int mx = 0; for (int i = 1; i <= cnt; i++) if (1ll*p[i]*p[i] <= n) mx = i; for (int i = mx; i >= 1; i--) { for (int j = 1; j <= tot && val[j] >= 1ll*p[i]*p[i]; j++) { int e = 1; ll v = p[i]; if (1ll*p[i+1]*p[i+1] > val[j]) h[j] = calh(j, i+1); while (v <= val[j]) { int t = 0; if (1LL*p[i+1]*p[i+1] > val[j]/v) { t = mo(calh(getin(val[j]/v), i+1)+1); } else t = mo(h[getin(val[j]/v)]+1); h[j] = mo(h[j]+1LL*(p[i]^e)*t%mod); ++ e; v *= p[i]; } } } printf("%dn", mo(h[getin(n)]+1)); return 0; }
|
近期评论