Description
Solution
Min_25筛模板题,具体可以看2018年zzt的论文。
注意一个地方:论文中的递推式
中,当
时,
会被计算两次,所以就不需要那个“
”了。
Code
/**************************************
* Au: Hany01
* Prob: LOJ6202
* Date: Jun 17th, 2018
* Email: [email protected]
**************************************/
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
typedef vector<int> VI;
#define File(a) freopen(a".in", "r", stdin), freopen(a".out", "w", stdout)
#define rep(i, j) for (register int i = 0, i##_end_ = j; i < i##_end_; ++ i)
#define For(i, j ,k) for (register int i = (j), i##_end_ = (k); i <= i##_end_; ++ i)
#define Fordown(i, j, k) for (register int i = (j), i##_end_ = (k); i >= i##_end_; -- i)
#define Set(a, b) memset(a, b, sizeof(a))
#define SZ(a) ((int)(a.size()))
#define ALL(a) a.begin(), a.end()
#define pb(a) push_back(a)
#define mp(a, b) make_pair(a, b)
#define INF (0x3f3f3f3f)
#define INF1 (2139062143)
#define Mod (1000000007)
#define y1 wozenmezhemecaia
#ifdef hany01
#define debug(...) fprintf(stderr, __VA_ARGS__)
#else
#define debug(...)
#endif
template<typename T> inline bool chkmax(T &a, T b) { return a < b ? a = b, 1 : 0; }
template<typename T> inline bool chkmin(T &a, T b) { return b < a ? a = b, 1 : 0; }
inline LL read() {
register char c_; register LL _, __;
for (_ = 0, __ = 1, c_ = getchar(); !isdigit(c_); c_ = getchar()) if (c_ == '-') __ = -1;
for ( ; isdigit(c_); c_ = getchar()) _ = (_ << 1) + (_ << 3) + (c_ ^ 48);
return _ * __;
}
const int maxn = 100105, maxs = 100100, N = 100100;
int tot, pri[maxn >> 1];
LL sum[maxn], n, inv2;
bitset<maxn> nap;
inline void Sieve()
{
static int t;
nap.reset();
For(i, 2, N) {
sum[i] = sum[i - 1];
if (!nap.test(i)) pri[++ tot] = i, (sum[i] += i) %= Mod;
for (register int j = 1; j <= tot && (t = pri[j] * i) <= N; ++ j) {
nap.set(t);
if (!(i % pri[j])) break;
}
}
}
inline LL Pow(LL a, LL b)
{
LL Ans = 1;
for ( ; b; b >>= 1, (a *= a) %= Mod) if (b & 1) (Ans *= a) %= Mod;
return Ans;
}
inline LL Sum(LL x) {
if (x == 1) return 1;
return (x % Mod * ((x + 1) % Mod) % Mod * inv2 % Mod) % Mod;
}
LL h[maxs << 1], lst[maxs << 1], H[maxs << 1];
int cnt, t1[maxn], t2[maxn], id;
inline int F(int x) { return x == 2 ? x + 1 : x - 1; }
inline void Calc(LL x)
{
static LL l, r, t;
cnt = 0;
for (l = 1; l <= x; l = r + 1) {
r = x / (t = (x / l)), lst[++ cnt] = t, h[cnt] = (Sum(t) - 1) % Mod, H[cnt] = (t - 1) % Mod;
t >= N ? t2[x / t] = cnt : t1[t] = cnt;
}
For(j, 1, tot) {
register LL bot = (LL)pri[j] * pri[j];
if (bot > x) break;
for (register int i = 1; lst[i] >= bot; ++ i) {
t = lst[i] / pri[j], id = t >= N ? t2[x / t] : t1[t];
(h[i] -= (LL)pri[j] * ((h[id] - sum[pri[j - 1]]) % Mod) % Mod) %= Mod;
(H[i] -= (LL)(H[id] - (j-1)) % Mod) %= Mod;
}
}
For(i, 1, cnt) {
(h[i] -= H[i]) %= Mod;
if (lst[i] >= 2) (h[i] += 2) %= Mod;
}
}
inline LL HH(LL x) {
return (x >= N ? h[t2[n / x]] : h[t1[x]]);
}
LL g(LL x, int m)
{
if (x == 1 || pri[m] >= x) return 0;
LL Ans = (HH(x) - (sum[pri[m]] - m)) % Mod;
if ((LL)pri[m] * pri[m] >= x) return (Ans - 2) % Mod;
//printf("%lld %d %lld %lld %d\n", x, m, (HH(x) + Mod) % Mod, (sum[pri[m]] + Mod) % Mod, m);
if (x >= 1) (Ans -= 2) %= Mod;
for (int i = m + 1, p; (LL)pri[i] * pri[i] <= x; ++ i) {
p = pri[i];
for (LL pe = p, e = 1; pe <= x; pe *= p, ++ e)
(Ans += (LL)(p ^ e) * ((e > 1) + g(x / pe, i)) % Mod) %= Mod;
}
return Ans;
}
int main()
{
#ifdef hany01
File("loj6053");
#endif
Sieve();
inv2 = Pow(2, Mod - 2);
Calc(n = read());
printf("%lld\n", (g(n, 0) + 1 + (n > 1) * 2 + Mod) % Mod);
return 0;
}
//寄相思,寒雨灯窗,芙蓉旧院。
// -- 吴文英《宴清都·秋感》