标签:const sum return ++ std rac lse its esc
求第 \(k\) 个 \(\mu=0\) 的数。\(k \leq 10^{10}\)
小于等于 \(x\) 的无法正确分解的数字个数为:
\[- \sum\limits_{i=2}^{\sqrt x}\mu(i){\left\lfloor\frac{x}{i^2}\right\rfloor}\]
相当于因数中有质数的平方的数,利用 \(\mu\) 函数容斥原理,二分 \(x\) 进行判断。
注意 \(\sum\limits_{i=1}^{\sqrt n}{\left\lfloor\frac{n}{i^2}\right\rfloor}\) 的整除分块应该是 \(r=sqrt(n / (n / (i * i)))\),证明待填坑。
#include <cstdio>
#include <cmath>
typedef long long LL;
const int N = 10000005;
int np[N], p[N], mu[N], sum[N], tot; LL k;
void getmu(int n) {
for (int i = 2; i <= n; ++i) {
if (!np[i]) p[++tot] = i, mu[i] = 1;
for (int j = 1; j <= tot && i * p[j] <= n; ++j) {
np[i*p[j]] = 1;
if (i % p[j] == 0) { mu[i*p[j]] = 0; break; }
mu[i*p[j]] = -mu[i];
}
}
for (int i = 1; i <= n; ++i) sum[i] = sum[i-1] + mu[i];
}
LL calc(LL n) {
LL res = 0, m = sqrt(n);
for (LL l = 2, r; l <= m; l = r + 1) {
r = sqrt(n / (n / (l * l)));
res += (sum[r] - sum[l-1]) * (n / (l * l));
}
return res;
}
int main() {
scanf("%lld", &k), getmu(1e7);
LL l = 4, r = 1e14;
while (l < r) {
LL mid = l + ((r - l) >> 1);
LL res = calc(mid);
if (res >= k) r = mid;
else l = mid + 1;
}
printf("%lld\n", l);
return 0;
}
标签:const sum return ++ std rac lse its esc
原文地址:https://www.cnblogs.com/fly-in-milkyway/p/9973686.html