[中山市选2011] 完全平方数
[题目链接]
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; }