码迷,mamicode.com
首页 > 其他好文 > 详细

[Vijos 1889] 天真的因数分解

时间:2018-11-17 15:59:40      阅读:229      评论:0      收藏:0      [点我收藏+]

标签:const   sum   return   ++   std   rac   lse   its   esc   

Description

求第 \(k\)\(\mu=0\) 的数。\(k \leq 10^{10}\)

Solution

小于等于 \(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)))\),证明待填坑。

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\n", l);
    return 0;
}

[Vijos 1889] 天真的因数分解

标签:const   sum   return   ++   std   rac   lse   its   esc   

原文地址:https://www.cnblogs.com/fly-in-milkyway/p/9973686.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!