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;
}

浙公网安备 33010602011771号