Description
求
∑i=1Nμ(i2)
以及
∑i=1Nφ(i2)
Solution
第一问puts("1");
第二问考虑杜教筛,首先发现式子求的就是
S(N)=∑i=1Nφ(i)i
我们令
f(x)=φ(i)i
发现
(f∗id)(n)=∑d|nφ(d)dnd=∑d|nφ(d)n
构造卷积,得
S(n)=∑i=1ni∑d|iφ(d)−∑i=2niS(⌊ni⌋)
整理,得
S(n)=n(n+1)(2n+1)6−∑i=2nS(⌊ni⌋)i
这个东西就可以杜教筛啦。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <tr1/unordered_map>
using namespace std;
using namespace tr1;
const int MOD = 1000000007;
const int N = 1000100;
const int INV = 166666668;
typedef long long ll;
int n, Pcnt, x, ans, res, tmp, pos;
int prime[N], phi[N], vis[N];
unordered_map<int, int> PHI;
inline void inc(int &x, int a) {
x += a;
while (x >= MOD) x -= MOD;
}
inline void dec(int &x, int a) {
x -= a;
while (x < 0) x += MOD;
}
int Phi(int x) {
if (x < N) return phi[x];
if (PHI.count(x)) return PHI[x];
int p = (ll)x * (x + 1) % MOD * (x * 2 + 1) % MOD * INV % MOD, pos, res;
for (int i = 2; i <= x; i = pos + 1) {
pos = x / (x / i);
res = (ll)(i + pos) * (pos - i + 1) / 2 % MOD * Phi(x / i) % MOD;
dec(p, res);
}
return PHI[x] = p;
}
int main(void) {
puts("1"); scanf("%d", &n);
for (int i = 2; i < N; i++) {
if (!vis[i]) {
prime[++Pcnt] = i;
phi[i] = i - 1;
}
for (int j = 1; j <= Pcnt && (x = prime[j] * i) < N; j++) {
vis[x] = 1;
if (i % prime[j]) {
phi[x] = phi[i] * phi[prime[j]];
} else {
phi[x] = phi[i] * prime[j];
break;
}
}
}
phi[1] = 1;
for (int i = 2; i < N; i++) {
phi[i] = (ll)phi[i] * i % MOD;
inc(phi[i], phi[i - 1]);
}
printf("%d\n", Phi(n));
return 0;
}