思路:这个题要求的是第K个非完全平方数且没有完全平方数因子的数,我们可以将这个问题转换为求这个区间的所有完全平方数且没有完全平方数因子的数的数量,这样就可以通过二分的方法来求解,具体的数量的可以通过容斥原理来求得,而此时可以用到莫比乌斯函数来做为系数。
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
#define MAXN 100100
#define MAXE 5
#define INF 0x7ffffff
#define MOD 1000000007
#define LL long long
#define ULL unsigned long long
#define pi 3.14159
using namespace std;
int mu[MAXN];
LL p[MAXN], cnt = 0;
bool prime[MAXN];
void init() {
memset(prime, true, sizeof(prime));
memset(mu, 0, sizeof(mu));
mu[1] = 1;
for (int i = 2; i <= 100010; ++i) {
if (prime[i]) {
p[cnt++] = i;
mu[i] = -1;
}
for (int j = 0; p[j] * i <= 100010; ++j) {
prime[i * p[j]] = false;
if (i % p[j] == 0) {
mu[i * p[j]] = 0;
break;
} else {
mu[i * p[j]] = -mu[i];
}
}
}
}
LL k;
bool check(LL mid) {
LL ans = 0;
for (LL i = 1; i * i <= mid; ++i) {
ans += mu[i] * (mid / (i * i));
}
return ans >= k;
}
int main() {
std::ios::sync_with_stdio(false);
init();
int T;
cin >> T;
for (int kase = 1; kase <= T; ++kase) {
cin >> k;
LL left = 1, right = 2 * k;
LL mid;
for (int i = 1; i <= 50; ++i) {
mid = (left + right) / 2;
if (check(mid)) {
right = mid;
} else {
left = mid;
}
}
cout << right << endl;
}
return 0;
}