hdu2588 GCD(欧拉函数)

题目链接: hdu2588 ( GCD )

给定 \(N,M\) ,求解 \(1\sim N\) 中满足条件 \((X,N)\ge M\)\(X\) 的个数。

\(p>=M\)\(N\) 的一个因子。

\(1\sim N\) 中满足条件 \((X,N)= p\)\(X\) 的个数,

即为 \(1\sim \frac Np\) 中满足条件 \((Y,\frac Np)= 1\)\(Y\) 的个数( \(Y=\frac Xp\) ),即 \(\Phi(N/p)\) ,其中 \(\Phi(x)\) 为欧拉函数。

遍历 \(N\) 的所有因子即可得到答案。

最坏时间复杂度不超过 \(O(\sqrt N\cdot \sqrt N)\) 。求欧拉函数的时间复杂度在 \(\log n\)\(\sqrt n\) 之间徘徊,因此实际时间复杂度应该远小于 \(O(\sqrt N\cdot \sqrt N)\)

/**
 * hdu2588 GCD
 *
 */

#include <cstdio>
#include <climits>

typedef long long LL;

LL phi(LL n)
{
    LL res = n;
    for (LL i = 2; i*i <= n; ++i) {
        if (n%i == 0) res = res/i*(i-1);
        while (n%i == 0) n /= i;
    }
    if (n > 1) res = res/n*(n-1);
    return res;
}

int main()
{
    int T;
    scanf("%d", &T);
    while (T--) {
        int n, m;
        scanf("%d%d", &n, &m);
        int i;
        int ans = 0;
        for (i = 1; i*i < n; ++i) {
            if (n%i == 0) {
                if (i >= m) ans += phi(n/i);
                if (n/i >= m) ans += phi(i);
            }
        }
        if (i*i == n && i >= m) ans += phi(i);
        printf("%d\n", ans);
    }
    return 0;
}

欧拉函数模板

欧拉函数 \(phi(n)\)\(1\sim n\) 中与 \(n\) 互质的数的个数。

\[\Phi(x)=x\prod_{i=1}^k(1-\frac1{p_i}),~其中p_1,p_2,\cdots,p_k为x的所有质因子 \]

typedef long long LL;
LL phi(LL n)
{
    LL res = n;
    for (LL i = 2; i*i <= n; ++i) {
        if (n%i == 0) res -= res/i;
        while (n%i == 0) n /= i;
    }
    if (n > 1) res -= res/n;
    return res;
}
posted @ 2021-02-16 23:12  Zewbie  阅读(98)  评论(0)    收藏  举报