【Luogu P4318】完全平方数

链接:

洛谷

题目大意:

求第 \(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;
}
posted @ 2021-11-16 10:55  Jayun  阅读(56)  评论(0编辑  收藏  举报