hdu 2588

Problem Description
The greatest common divisor GCD(a,b) of two positive integers a and b,sometimes written (a,b),is the largest divisor common to a and b,For example,(1,2)=1,(12,18)=6.
   (a,b) can be easily found by the Euclidean algorithm. Now Carp is considering a little more difficult problem:
   Given integers N and M, how many integer X satisfies 1<=X<=N and (X,N)>=M.
 

Input
The first line of input is an integer T(T<=100) representing the number of test cases. The following T lines each contains two numbers N and M (2<=N<=1000000000, 1<=M<=N), representing a test case.
 

Output
For each test case,output the answer on a single line.
 

Sample Input
  
  
3 1 1 10 2 10000 72
 

Sample Output
  
  
1 6 260
 

Source
 

Recommend
lcy   |   We have carefully selected several similar problems for you:   1695  1787  2824  2582  1286 
题目的意思很简单啦,就是问gcd(x,N)>=M,其中1<=x<=N,1<=M<=N,满足这样条件的x有多少个,
首先呢,设x,N的最大公约数为d,x=p*d,N=q*d,那么p和q是互质的,这个很显然嘛.在d>=M的情况下,问有多少个p和q互质,题目就转换成了求q的欧拉函数值,当然需要提一下的是,当x=N时,p=1,而euler(1)=1,这种情况也被包括了.d最小可以取M,最大可以取N,而N是10e,如果遍历N-M+1次,显然会超时,我们需要判断一下d是否是N的因子,而找一个数的因子复杂度是O(N),我们再判断一下,i或者是N/i是否大于d即可,这样复杂度就降下来了.( 偷笑 偷笑 偷笑 偷笑)
代码
#include <iostream>

using namespace std;
long long euler(long long n)
{
  long long res=n,a=n;
  for(int i=2;i*i<=a;i++)
  {
   if(a%i==0)
   {
    res=res/i*(i-1);//先进行除法是为了防止数据的溢出
    while(a%i==0) a/=i;
   }
  }
  if(a>1) res=res/a*(a-1);
  return res;
}
int main()
{
    int t;
    long long n,m,num;
    cin>>t;
    while(t--)
    {
     num=0;
     cin>>n>>m;
     for(int i=1;i*i<=n;i++)//i应该从1开始,不信试一试
     {
      if(n%i==0)
      {
       if(i>=m)
        num=num+euler(n/i);
       if(n/i>=m&&i*i!=n)//这里需要特判一下啦
        num=num+euler(i);
      }
     }
    cout <<num<< endl;
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值