求
\[\sum_{i=1}^n\sum_{d|i}\mu(d)\sigma_0^2(\frac i d) \]\(n\le 10^9, T \le 10\)。
讲题的时候讲的可能不太清晰。这里给出一个详细的过程。
许多人都发现了这道题是一个min_25筛的版题并爆切了,但是否有人尝试证明了呢?
根据SDOI2015 约数个数和,我们得到 \(\sigma_0(ij)=\sum\limits_{x|i}\sum\limits_{y|i}[\gcd(x,y)=1]\) 。
受此启发,加上式子中有 \(\mu\) 函数,我们可以考虑反推出反演过程,即(从下往上看):
\(\begin{aligned} \sum_{i=1}^n\sigma_0(i^2) &= \sum\limits_{i=1}^n\sum_{x|i}\sum_{y|i}[\gcd(x,y)=1] \\ &= \sum\limits_{i=1}^n\sum_{x|i}\sum_{y|i}\sum_{d|\gcd(x,y)}\mu(d) \\ &= \sum_{i=1}^n\sum_{d|i}\mu(d)\sum_{d|x,x|i}\sum_{d|y,y|i}1 \\ &= \sum_{i=1}^n\sum_{d|i}\mu(d)\sigma_0^2(\frac i d)\end{aligned}\)
显然 \(f(x)=d(x^2)\) 是一个积性函数,并且有\(f(p^c)=2c+1\),这与大家打表出来的结果一致。
最后本人猜测出题人也是这么想到的。
#include <cmath> #include <cstdio> #include <algorithm> #define fo(i, a, b) for(int i = (a); i <= (b); ++i) #define ll long long using namespace std; const int N = 32e4; bool v[N + 10]; int tot; ll p[N + 10], n, sq, m, w[N + 10], sum[N + 10], g[N + 10], id1[N + 10], id2[N + 10]; void pre() { fo(i, 2, N) { if(!v[i]) ++tot, p[tot] = i; for(int j = 1; p[j] * i <= N && j <= tot; ++j) { v[i * p[j]] = 1; if(!(i % p[j])) break; } } fo(i, 1, tot) sum[i] = i * 3; } ll getid(ll x) { return x <= sq ? id1[x] : id2[n / x];} ll S(ll x, int j) { if(p[j] > x) return 0; ll Ans = g[getid(x)] - sum[j]; for(int i = j + 1; i <= tot && p[i] * p[i] <= x; ++i) for(ll e = 1, sp = p[i]; sp <= x; sp *= p[i], ++e) Ans += (e * 2 + 1) * (S(x / sp, i) + (e > 1)); return Ans; } int main() { freopen("function.in", "r", stdin); freopen("function.out", "w", stdout); pre(); int T; for(scanf("%d", &T); T; --T) { scanf("%lld", &n), sq = sqrt(n), m = 0; for(ll l = 1, r; l <= n; l = r + 1) { r = (n / (n / l)), w[++m] = n / l; g[m] = 3 * (w[m] - 1); w[m] <= sq ? id1[w[m]] = m : id2[n / w[m]] = m; } fo(i, 1, tot) for(int j = 1; j <= m && p[i] * p[i] <= w[j]; ++j) g[j] -= (g[getid(w[j] / p[i])] - sum[i - 1]); printf("%lld\n", S(n, 0) + 1); } return 0; }