链接:
题目大意:
求第 \(k\) 个非完全平方数(或其倍数)。
正文:
换句话说,题目要我们求第 \(k\) 个质因子最高次小于二的数,这就很 \(\mu\)。
求第 \(k\) 大考虑用二分,每次判断 \([1,\mathrm{mid}]\) 中的合法数是否大于 \(k\)。
代码:
const int N = 5e4 + 10;
inline ll Read() {
ll x = 0, f = 1;
char c = getchar();
while (c != '-' && (c < '0' || c > '9')) c = getchar();
if (c == '-') f = -f, c = getchar();
while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0', c = getchar();
return x * f;
}
int pri[N], mu[N], cnt;
bool vis[N];
void init () {
mu[1] = 1;
for (int i = 2; i <= N - 10; i++) {
if (!vis[i]) pri[++cnt] = i, mu[i] = -1;
for (int j = 1; i * pri[j] <= N - 10 && j <= cnt; j++) {
vis[i * pri[j]] = 1;
if (i % pri[j] == 0) break;
mu[i * pri[j]] = -mu[i];
}
}
}
ll n;
ll check (ll x) {
ll sum = 0;
for (int i = 1; i * i <= x; i++)
sum += mu[i] * (x / (i * i));
return sum;
}
int main() {
// freopen(".in", "r", stdin);
// freopen(".out", "w", stdout);
init();
for (int t = Read(); t--; ) {
n = Read();
ll l = n, r = 1644934082ll, ans;
while (l < r) {
ll mid = l + r >> 1;
if (check(mid) >= n) r = mid;
else l = mid + 1;
}
printf ("%lld\n", r);
}
return 0;
}