[Vijos 1889] 天真的因数分解
Posted fly-in-milkyway
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Vijos 1889] 天真的因数分解相关的知识,希望对你有一定的参考价值。
Description
求第 (k) 个 (mu=0) 的数。(k leq 10^{10})
Solution
小于等于 (x) 的无法正确分解的数字个数为:
[- sumlimits_{i=2}^{sqrt x}mu(i){leftlfloorfrac{x}{i^2} ight floor}]
相当于因数中有质数的平方的数,利用 (mu) 函数容斥原理,二分 (x) 进行判断。
注意 (sumlimits_{i=1}^{sqrt n}{leftlfloorfrac{n}{i^2} ight floor}) 的整除分块应该是 (r=sqrt(n / (n / (i * i)))),证明待填坑。
Code
#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
", l);
return 0;
}
以上是关于[Vijos 1889] 天真的因数分解的主要内容,如果未能解决你的问题,请参考以下文章