diff --git a/TangDou/Topic/Mobius/P4318.cpp b/TangDou/Topic/Mobius/P4318.cpp index d25ed33..073318c 100644 --- a/TangDou/Topic/Mobius/P4318.cpp +++ b/TangDou/Topic/Mobius/P4318.cpp @@ -1,29 +1,43 @@ #include using namespace std; -int t, k, z[100005], p[100005], mu[100005]; -long long check(long long g) { - long long res = 0; - for (int i = 1; i * i <= g; i++) - res = res + mu[i] * (g / i / i); +const int N = 100010; - return res; -} -int main() { +// 筛法求莫比乌斯函数(枚举约数) +int mu[N], sum[N]; // sum[N]:梅滕斯函数,也就是莫比乌斯函数的前缀和 +int primes[N], cnt; +bool st[N]; +void get_mobius(int n) { mu[1] = 1; - for (int i = 2; i <= 100000; i++) { - if (!z[i]) { - p[++p[0]] = i; + for (int i = 2; i <= n; i++) { + if (!st[i]) { + primes[cnt++] = i; mu[i] = -1; } - for (int j = 1; j <= p[0] && i * p[j] <= 100000; j++) { - z[i * p[j]] = 1; - if (i % p[j] == 0) { - mu[i * p[j]] = 0; + for (int j = 0; primes[j] <= n / i; j++) { + int t = primes[j] * i; + st[t] = true; + if (i % primes[j] == 0) { + mu[t] = 0; break; } - mu[i * p[j]] = -mu[i]; + mu[t] = -mu[i]; } } + // 维护u(x)前缀和:梅滕斯函数 + for (int i = 1; i <= n; i++) sum[i] = sum[i - 1] + mu[i]; +} +long long check(long long g) { + long long res = 0; + for (int i = 1; i * i <= g; i++) + res = res + mu[i] * (g / i / i); + + return res; +} + +int main() { + get_mobius(N - 1); + + int t, k; cin >> t; while (t--) { cin >> k;