/* I will wait for you */ #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <ctime> #include <algorithm> #include <iostream> #include <fstream> #include <vector> #include <queue> #include <deque> #include <set> #include <map> #include <string> #define make make_pair #define fi first #define se second using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int, int> pii; typedef map<int, int> mii; const int maxn = 100010; const int maxm = 1010; const int maxs = 26; const int inf = 0x3f3f3f3f; const int P = 1000000007; const double error = 1e-9; inline ll read() { ll x = 0, f = 1; char ch = getchar(); while (ch < '0' || ch > '9') f = (ch == '-' ? -1 : 1), ch = getchar(); while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar(); return x * f; } int n, mu[maxn], pri[maxn], ma[maxn]; ll ans = 2; void init() { mu[1] = 1; for (int i = 2; i * i <= n; i++) if (pri[i] == 0) { for (int j = i * i; j <= n; j += i) pri[j] = 1, ma[j] = max(ma[j], i); } for (int i = 2; i <= n; i++) { if (pri[i] == 0) mu[i] = -1; else if (i / ma[i] % ma[i] == 0) mu[i] = 0; else mu[i] = -mu[i / ma[i]]; } } int main() { n = read() - 1, init(); for (int i = 1; i <= n; i++) ans += mu[i] * (n / i) * (n / i); printf("%lld\n", ans); return 0; }
想了想其实就是欧拉函数的前缀和.现在看到互质第一反应已经是莫比苏斯反演了.
/* I will wait for you */ #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <ctime> #include <algorithm> #include <iostream> #include <fstream> #include <vector> #include <queue> #include <deque> #include <set> #include <map> #include <string> #define make make_pair #define fi first #define se second using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int, int> pii; typedef map<int, int> mii; const int maxn = 100010; const int maxm = 1010; const int maxs = 26; const int inf = 0x3f3f3f3f; const int P = 1000000007; const double error = 1e-9; inline ll read() { ll x = 0, f = 1; char ch = getchar(); while (ch < '0' || ch > '9') f = (ch == '-' ? -1 : 1), ch = getchar(); while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar(); return x * f; } int n, fa[maxn], pri[maxn], ma[maxn]; ll ans = 3; void init() { for (int i = 2; i * i <= n; i++) if (pri[i] == 0) { for (int j = i * i; j <= n; j += i) pri[j] = 1, ma[j] = max(ma[j], i); } for (int i = 2; i <= n; i++) { if (pri[i] == 0) fa[i] = i - 1; else if (i / ma[i] % ma[i] == 0) fa[i] = fa[i / ma[i]] * ma[i]; else fa[i] = fa[i / ma[i]] * (ma[i] - 1); } } int main() { n = read() - 1, init(); for (int i = 1; i <= n; i++) ans += 2 * fa[i]; printf("%lld\n", ans); return 0; }