這個式子的推導過程放在個人博客《數論公式總結》裏面了網絡
#include<cstdio> #include<unordered_map> using namespace std; const int maxn = 5e6 + 10; const int mod = 1e9 + 7; int ksm(int a, int b) { int ans = 1, base = a; while (b) { if (b & 1) ans = 1ll * ans * base % mod; b >>= 1; base = 1ll * base * base % mod; } return ans; } int inv6, inv2; int prime[maxn], phi[maxn], pre[maxn]; bool no_prime[maxn]; int shai(int n) { int cnt = 0; no_prime[1] = phi[1] = 1; for (int i = 2; i <= n; i++) { if (!no_prime[i]) prime[++cnt] = i, phi[i] = i - 1; for (int j = 1; j <= cnt && i * prime[j] <= n; j++) { no_prime[prime[j] * i] = 1; phi[prime[j] * i] = i % prime[j] == 0 ? phi[i] * prime[j] : phi[i] * (prime[j] - 1); if (i % prime[j] == 0) break; } } for (int i = 1; i <= n; i++) pre[i] = (1ll * pre[i - 1] + 1ll * i * phi[i] % mod) % mod; return cnt; } unordered_map<int, int> rec; int S(int n) { if (n <= maxn - 10) return pre[n]; if (rec[n]) return rec[n]; long long ans = 1ll * n * (n + 1) % mod * (2 * n + 1) % mod * inv6 % mod; int l = 2, r = n; while (l <= n) { r = n / (n / l); ans = ((ans - 1ll * (l + r) * (r - l + 1) % mod * inv2 % mod * S(n / l) % mod) % mod + mod) % mod; l = r + 1; } return rec[n] = ans; } void solve() { inv6 = ksm(6, mod - 2); inv2 = ksm(2, mod - 2); shai(maxn - 10); int t; scanf("%d", &t); while (t--) { int n, a, b; scanf("%d%d%d", &n, &a, &b); printf("%lld\n", 1ll * (S(n) - 1 + mod) % mod * inv2 % mod); } } int main() { solve(); return 0; }