luogu P4318 完全平方數
阿新 • • 發佈:2020-09-20
今天膜你賽的時候我想推一個 \(\sum\limits_{i=1}^n \mu^2(i)\),結果太弱智了沒推出來,然後就來看了這道題。
首先考慮二分答案。現在問題就轉化為如何求上述式子。
對每個質因子的平方進行容斥,發現對於每個數容斥係數恰好是 \(u(i)\)。所以原式即為 \(\sum\limits_{i=1}^{\lfloor\sqrt n \rfloor}\mu(i)\lfloor \frac{n}{i^2}\rfloor\)。時間複雜度 \(O(\sqrt n+TlogK)\)。
程式碼:
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #define int long long using namespace std; const int N = 100000; int k, a[N + 9], p[N], cnt, u[N + 9]; void prework() { u[1] = 1; for (int i = 2; i <= N; i++) { if (!a[i]) a[i] = i, p[++cnt] = i, u[i] = -1; for (int j = 1; j <= cnt; j++) { if (p[j] > a[i] || p[j] > N / i) break; a[p[j] * i] = p[j]; if (i % p[j]) u[p[j] * i] = u[p[j]] * u[i]; } } } void init() { scanf("%lld", &k); } int check(int n) { int res = 0; for (int i = 1; i * i <= n; i++) res += u[i] * (n / (i * i)); return res; } void work() { int l = 1, r = 2e10, mid; while (l <= r) { mid = l + r >> 1; if (check(mid) < k) l = mid + 1; else r = mid - 1; } printf("%lld\n", l); } signed main() { prework(); int T; scanf("%lld", &T); while (T--) init(), work(); return 0; }