[中山市選2011] 完全平方數
阿新 • • 發佈:2018-11-01
[題目連結]
https://www.lydsy.com/JudgeOnline/problem.php?id=2440
[演算法]
首先 , 不妨二分答案mid , 我們需要判斷的是一個形如"[1 , mid]區間中是否有 >= k個不是完全平方數倍數的數“
考慮容斥 , 顯然 , 答案為 : mid - 有1個質因子的數的倍數個數 + 有兩個質因子的數的倍數個數 - ... + ....
不難發現 , 每一項的係數為其莫比烏斯函式
預處理莫比烏斯函式即可
時間複雜度 : O(NlogN)
[程式碼]
#include<bits/stdc++.h> using namespace std; #define MAXD 1000010 typedef long long LL; LL k; int miu[MAXD];bool visited[MAXD]; template <typename T> inline void chkmax(T &x , T y) { x = max(x , y); } template <typename T> inline void chkmin(T &x , T y) { x = min(x , y); } template <typename T> inline void read(T &x) { T f = 1; x = 0; char c = getchar(); for (; !isdigit(c); c = getchar()) if(c == '-') f = -f; for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0'; x *= f; } inline void preprocess() { for (int i = 1; i < MAXD; i++) { miu[i] = 1; visited[i] = false; } for (int i = 2; i < MAXD; i++) { if (visited[i]) continue; miu[i] = -1; for (int j = 2; 1LL * i * j < MAXD; j++) { visited[i * j] = true; if (j % i == 0) miu[i * j] = 0; else miu[i * j] *= -1; } } } inline LL calc(LL mid) { LL ret = 0; for (int i = 1; 1LL * i * i <= mid; i++) ret += 1LL * miu[i] * (1LL * mid / (1LL * i * i)); return ret; } int main() { int T; read(T); preprocess(); while (T--) { read(k); LL l = 1 , r = (LL)1e10 , ans; while (l <= r) { LL mid = (l + r) >> 1; if (calc(mid) >= k) { ans = mid; r = mid - 1; } else l = mid + 1; } printf("%lld\n" , ans); } return 0; }