diff --git a/TangDou/Topic/Mobius/SQP4168.cpp b/TangDou/Topic/Mobius/SQP4168.cpp index 720daa5..93c943a 100644 --- a/TangDou/Topic/Mobius/SQP4168.cpp +++ b/TangDou/Topic/Mobius/SQP4168.cpp @@ -1,14 +1,14 @@ -#include -#include -#include +#include using namespace std; #define int long long #define endl "\n" -const int N = 1e7 + 10; // 枚举到sqrt(1e14)=1e7即可 +const int M = 110, N = 10000010; + +int t, m, sqrtN, n, ans, q[M]; // 筛法求莫比乌斯函数(枚举约数) -int mu[N], s1[N], s2[N]; // s1[N]:梅滕斯函数,也就是莫比乌斯函数的前缀和 +int mu[N], sum[N]; // sum[N]:梅滕斯函数,也就是莫比乌斯函数的前缀和 int primes[N], cnt; bool st[N]; void get_mobius(int n) { @@ -29,34 +29,30 @@ void get_mobius(int n) { } } // 维护u(x)前缀和:梅滕斯函数 - for (int i = 1; i <= n; i++) s1[i] = s1[i - 1] + mu[i]; - for (int i = 1; i <= n; i++) s2[i] = s2[i - 1] + mu[i] * mu[i]; -} - -int calc(int n) { - if (n <= N) return s2[n]; - int res = 0, m = sqrt(n); - for (int l = 1, r; l <= m; l = r + 1) { - r = min((int)sqrt(n / (n / (l * l))), m); - res += (n / (l * l)) * (s1[r] - s1[l - 1]); - } - return res; + for (int i = 1; i <= n; i++) sum[i] = sum[i - 1] + mu[i]; } signed main() { #ifndef ONLINE_JUDGE freopen("SQP4168.in", "r", stdin); - /* - 1 - 608 - 60792710185947 - */ #endif - int n, T; - cin >> T; - get_mobius(N - 1); - while (T--) { - cin >> n; - cout << calc(n) << endl; + cin >> t; + for (int i = 1; i <= t; i++) { + cin >> q[i]; + n = max(n, q[i]); } -} + sqrtN = sqrt(n); + + get_mobius(sqrtN); // 线性求莫比乌斯函数, 前缀和 + + for (int i = 1; i <= t; i++) { + n = q[i]; + ans = 0; + for (int l = 1, r; l <= n; l = r + 1) { + if (n / (l * l) == 0) { break; } + r = sqrt(n / (n / (l * l))); + ans += n / (l * l) * (sum[r] - sum[l - 1]); + } + printf("%lld\n", ans); + } +} \ No newline at end of file