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.
(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
题目的意思很简单啦,就是问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即可,这样复杂度就降下来了.(
)
![偷笑](http://static.blog.csdn.net/xheditor/xheditor_emot/default/titter.gif)
![偷笑](http://static.blog.csdn.net/xheditor/xheditor_emot/default/titter.gif)
![偷笑](http://static.blog.csdn.net/xheditor/xheditor_emot/default/titter.gif)
![偷笑](http://static.blog.csdn.net/xheditor/xheditor_emot/default/titter.gif)
代码
#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;
}