题目大意

给定积性函数 $f(p^c) = p \oplus c$。对 $1000000007$ 取模求前缀和。

分析

Min25 板子题。

const ll mod = 1000000007, inv2 = 500000004;
const int maxn = 200001;
ll n, prime[maxn], cnt, w[maxn], s[maxn], c[maxn];
ll sqrt_n, m;

ll mo(ll x) {
	return (x + mod) % mod;
}

ll f_p(ll p, ll e) {
	return p ^ e;
}

int id(ll x) {
	return x <= sqrt_n ? x : m - (n / x) + 1;
}

ll F(long long n, int k) {
	if (n <= prime[k])
		return 0;
	ll ret = s[id(n)] - s[prime[k]];
	for (int i = k + 1; i <= cnt && prime[i] * prime[i] <= n; i++) {
		ll pi = prime[i], pk = pi;
		for (int c = 1; pk * pi <= n; c++, pk *= pi)
			ret += f_p(pi, c) * F(n / pk, i) + f_p(pi, c + 1);
	}
	return mo(ret);
}

int main() {
	n = rr();
	sqrt_n = sqrt(n + 0.01);
	m = cnt = 0;
	for (ll l = 1, r; l <= n; l = r + 1) {
		w[++m] = r = n / (n / l);
		ll mr = mo(r);
		s[m] = mr * (mr + 1) % mod * inv2 % mod - 1;
		c[m] = mr - 1;
	}
	for (ll p = 2; p <= sqrt_n; p++) {
		if (c[p] != c[p - 1]) {
			prime[++cnt] = p;
			for (ll j = m; w[j] >= p * p; j--) {
				s[j] = mo(s[j] - p * mo(s[id(w[j] / p)] - s[p - 1]));
				c[j] = mo(c[j] - (c[id(w[j] / p)] - c[p - 1]));
			}
		}
	}
	for (int i = 2; i <= m; i++)
		s[i] = mo(s[i] - c[i] + 2);
	printf("%lld", F(n, 0) + 1);
}