小 X 討厭完全平方數及其正整數倍(即含平方因子的數)。給定 K,求第 K 個「不含平方因子」的正整數(無平方因子數 / Square-free numbers)。
直接求第 K 個無平方因子數困難,轉而二分答案 x,判斷 [1, x] 區間內有多少無平方因子數。
設 μ 為莫比烏斯函數:
根據容斥原理,[1, x] 內無平方因子數個數為:
ans = Σᵢ₌₁^⌊√x⌋ μ(i) × ⌊x / i²⌋
證明略:利用 μ 函數特性過濾含平方因子的數。
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int MAXN = 50005;
int mu[MAXN], primes[MAXN], cnt;
bool vis[MAXN];
// 線性篩求莫比烏斯函數
void linear_sieve() {
mu[1] = 1;
for (int i = 2; i < MAXN; ++i) {
if (!vis[i]) {
primes[++cnt] = i;
mu[i] = -1;
}
for (int j = 1; j <= cnt && primes[j] * i < MAXN; ++j) {
vis[primes[j] * i] = true;
if (i % primes[j] == 0) {
mu[primes[j] * i] = 0;
break;
} else {
mu[primes[j] * i] = -mu[i];
}
}
}
}
// 計算 [1, x] 內無平方因子數個數
ll calc(int x) {
ll ans = 0;
int lim = sqrt(x);
for (int i = 1; i <= lim; ++i)
ans += (ll)(x / (i * i)) * mu[i];
return ans;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
linear_sieve();
int T; cin >> T;
while (T--) {
int k; cin >> k;
ll l = k, r = 2e9, ans = r;
while (l <= r) {
ll mid = (l + r) >> 1;
if (calc(mid) >= k) {
ans = mid;
r = mid - 1;
} else {
l = mid + 1;
}
}
cout << ans << '\n';
}
return 0;
}