我好像只过了模板题
感觉很迷
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 4e5 + 10;
const int mod = 1e9 + 7;
const int iv2 = 500000004;
const int iv6 = 166666668;
int p[N], vis[N], tot = 0;
int sp1[N], sp2[N], sq, m = 0;
ll n, w[N];
int id1[N], id2[N], g1[N], g2[N];
int add(int x){return x >= mod ? x - mod : x;}
int sub(int x){return x < 0 ? x + mod : x;}
void Add(int &x, int y){if((x += y) >= mod && (x -= mod));}
void Sub(int &x, int y){if((x -= y) < 0 && (x += mod));}
int id(ll x)
{
if(x <= sq) return id1[x];
return id2[n / x];
}
int S(ll n, int k)
{
if(p[k] >= n) return 0;
int t = id(n), res = sub(sub(g2[t] - g1[t]) - sub(sp2[k] - sp1[k]));
for(int i = k + 1; i <= tot && 1ll * p[i] * p[i] <= n; i++)
{
int q = p[i];
for(ll e = q, c = 1; e <= n; e *= q, c++)
{
int o = e % mod;
Add(res, 1ll * o * add(o - 1 + mod) % mod * (S(n / e, i) + (c > 1)) % mod);
// cout << n <<" "<< k <<" "<< 1ll * o * add(o - 1 + mod) % mod << endl;
}
}
return res;
}
int qpow(int a, int b)
{
int res = 1;
for(; b; b >>= 1, a = 1ll * a * a % mod) if(b & 1) res = 1ll * res * a % mod;
return res;
}
void sieve(int n)
{
vis[1] = 1;
for(int i = 2; i <= n; i++)
{
if(!vis[i]) p[++tot] = i;
for(int j = 1; j <= tot && p[j] * i <= n; j++)
{
vis[i * p[j]] = 1;
if(i % p[j] == 0) break;
}
}
for(int i = 1; i <= tot; i++) sp1[i] = add(sp1[i - 1] + p[i]), sp2[i] = add(sp2[i - 1] + 1ll * p[i] * p[i] % mod);
return;
}
int S1(ll n)
{
n %= mod;
return n * (n + 1) % mod * iv2 % mod;
}
int S2(ll n)
{
n %= mod;
return n * (n + 1) % mod * (2 * n % mod + 1) % mod * iv6 % mod;
}
int main()
{
scanf("%lld", &n);
sq = (int) sqrt(n) + 1;
sieve(sq);
for(ll l = 1, r; l <= n; l = r + 1)
{
r = n / (n / l);
w[++m] = r;
if(r <= sq) id1[w[m]] = m;
else id2[n / w[m]] = m;
g1[m] = sub(S1(r) - 1);
g2[m] = sub(S2(r) - 1);
}
for(int i = 1; i <= tot; i++)
{
ll sqr = 1ll * p[i] * p[i];
for(int j = m; j >= 1 && w[j] >= sqr; j--)
{
Sub(g1[j], 1ll * p[i] * sub(g1[id(w[j] / p[i])] - sp1[i - 1]) % mod);
Sub(g2[j], 1ll * p[i] * p[i] % mod * sub(g2[id(w[j] / p[i])] - sp2[i - 1]) % mod);
}
}
printf("%d
", add(S(n, 0) + 1));
return 0;
}