HDU P2588 GCD___欧拉函数

题目大意:

给出T组数,每组数给出一对数N,M,求1~N之间有多少个数使得 gcd(X,N)>= M,输出满足的数的个数。

T<=100

2<=N<=1000000000, 1<=M<=N

题解:

显然直接暴力的是话时间肯定会炸。

我们设 s=gcd(X,N)

则必有 a*s = X , 且 b*s = N

并且我们可以知道gcd(a,b)必定为1

因为如果不为1,则s肯定能乘上一个gcd(a,b),

则我们可以知道满足gcd(a,b)= 1 的必定满足 gcd(X,N)= s

所以满足的X 显然有 φ(b)个,即b的欧拉函数

因为s是N的约数,

所以我们可以通过s,

去得出b,

然后去计算b的欧拉函数

枚举s能够做到根号的时间复杂度

求b的欧拉函数,也是根号的时间复杂度

所以就很优秀了

代码:

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#define LL long long

using namespace std;

int euler(int x){
    int phi = x;
    for (int i = 2; i*i <= x; i++)
         if (x%i == 0){
             phi -= phi/i;
             while (x%i == 0) x /= i; 
         }
    if (x > 1) phi -= phi/x; 
    return phi;
}

int main(){
    int T;
    scanf("%d",&T);
    while (T--){
           int n,m;
           scanf("%d%d",&n,&m);
           int ans = 0;
           for (int i = 1; i*i <= n; i++)
                if (n%i == 0){
                       if (i >= m) ans += euler(n/i);
                       if (n/i >= m && n/i != i) ans += euler(i);
                }
           printf("%d\n",ans);
    }
    return 0;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值