题目大意

定义

$$ f (n) = \sum_{d \mid n} d \left[ \gcd \left( d, \frac{n}{d} \right) = 1 \right] $$

求其前缀和 $S(n)$。

分析

首先 Min25 筛是过不了的,内存不够。先推式子

$$ \begin{aligned} S (n) &= \sum_{i = 1}^n \sum_{d \mid i} d \left[ \gcd \left( d, \frac{i}{d} \right) = 1 \right] \\ &= \sum_{d = 1}^n \sum_{i = 1}^n d [d \mid i] \left[\gcd \left( d, \frac{i}{d} \right) = 1 \right] \\ &= \sum_{d = 1}^n \sum_{i = 1}^{n / d} d [\gcd (i, d) = 1] \end{aligned} $$

看到 $\gcd = 1$ 就应该想起来 Mobius 反演,容易化简有

$$ S (n) = \sum_{d = 1}^n \sum_{i = 1}^{n / d} d \sum_{u \mid \gcd (i, d)} \mu(u) = \sum_{u = 1}^{\sqrt{n}} u \mu (u) \sum_{d = 1}^{n / u^2} d \left\lfloor \frac{n}{d u^2} \right\rfloor $$

用数论分块即可,计算复杂度 $O ( \sqrt{n} \log n )$。

const ll maxn = 1e6 + 20;
const ll mod = 1e9 + 7;

bool notp[maxn];
int prime[maxn / 10], cnt;
ll mu[maxn];
void sieve(int n); // 筛 Mobius 函数

ll g[maxn];

ll G(ll n) {
	if (n <= 1e6 && g[n] > 0)
		return g[n]; // 不做记忆化会 T
	__int128_t ret = 0;
	for (ll l = 1, r; l <= n; l = r + 1) {
		r = n / (n / l);
		__int128_t t = __int128_t(l + r) * (r - l + 1) / 2;
		ret += t * (n / l);
	}
	if (n <= 1e6)
		g[n] = ret % mod;
	return ret % mod;
}

int main() {
	ll ttt = rr();
	sieve(1e6 + 1);
	for (ll i = 1; i <= 1e6+1; i++) {
		mu[i] = (mu[i - 1] + mu[i] * i) % mod;
	}
	while (ttt--) {
		ll n = rr(), sn = sqrt(n * 1.0);
		__int128_t ans = 0;
		for (ll l = 1, r; l <= sn; l = r + 1) {
			ll t = n / l / l;
			r = sqrt(n / (n / l / l) * 1.0);
			ans += (mu[r] - mu[l - 1]) * G(n / l / l);
		}
		ans = (ans % mod + mod) % mod;
		printf("%lld\n", ll(ans));
	}
	return 0;
}