题目描述
https://loj.ac/p/6682
简要题意:给定 $n$,求 $\frac{1}{2}\sum_{i=1}^n\sigma_0^2(i)-\sigma_0(i)$
$n\le 10^{10}$
Solution
注意到 $\sum_{i=1}^n\sigma_0(i)=\sum_{i=1}^n\lfloor\frac{n}{i}\rfloor$,对于 $\sum_{i=1}^n\sigma_0^2(i)$ 我们可以考虑用 $Min\underline{}25$ 筛
我们令 $f(x)=\sigma_0(x)^2$,这个东西显然是积性函数,且 $f(p^x)=(x+1)^2$
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
| #include <iostream> #include <cmath> #define ll long long #define maxn 200010 using namespace std;
const int p = 998244353;
ll pow_mod(ll x, ll n) { ll s = 1; for (; n; n >>= 1, x = x * x % p) if (n & 1) s = s * x % p; return s; }
ll n;
int pri[maxn], cnt; bool isp[maxn]; ll sp[maxn]; void init_isp(int n) { for (int i = 2; i <= n; ++i) { if (!isp[i]) { pri[++cnt] = i; sp[cnt] = sp[cnt - 1] + 4; } for (int j = 1; j <= cnt && i * pri[j] <= n; ++j) { isp[i * pri[j]] = 1; if (i % pri[j] == 0) break; } } }
ll id1[maxn], id2[maxn], Sn; int get_id(ll x) { return x <= Sn ? id1[x] : id2[n / x]; }
ll g[maxn], w[maxn]; int num; void init_min25(ll n) { for (ll l = 1, r; l <= n; l = r + 1) { r = n / (n / l); w[++num] = n / l; g[num] = 4 * (n / l) % p - 4; if (w[num] <= Sn) id1[w[num]] = num; else id2[n / w[num]] = num; } for (int i = 1; i <= cnt; ++i) for (int j = 1; j <= num && 1ll * pri[i] * pri[i] <= w[j]; ++j) g[j] = (g[j] - (g[get_id(w[j] / pri[i])] - sp[i - 1])) % p; }
ll S(ll n, int m) { if (pri[m] >= n) return 0; ll ans = (g[get_id(n)] - sp[m]) % p; for (int i = m + 1; i <= cnt && 1ll * pri[i] * pri[i] <= n; ++i) for (ll x = 1, mul = pri[i]; mul <= n; mul *= pri[i], ++x) ans = (ans + (x + 1) * (x + 1) * (S(n / mul, i) + (x > 1))) % p; return ans; }
int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
cin >> n; Sn = sqrt(n); init_isp(Sn); init_min25(n); ll ans = 0; for (ll l = 1, r; l <= n; l = r + 1) { r = n / (n / l); ans = (ans - (r - l + 1) % p * (n / l)) % p; } ans = (ans + S(n, 0) + 1) * pow_mod(2, p - 2) % p; cout << (ans + p) % p << "\n"; return 0; }
|