G-数论

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



题意:给你两个数n,m,让你从比n小(等于也可以)的数中选一个数与n求最大公约数,问你求出的最大公约数大于等于m的数共有多少个

分析:一开始我的思路是定义一个数组存1~n个数,然后将每一个数分别与n求最大公约数,再将求出的最大公约数与m进行比较,符合条件就加1,否则即循环,但这样做的话很复杂,而且写到后面总觉得有些东西写不出来,不好实现。然后参考了别人的思路,又学了一下欧拉函数的应用。还不是很理解
定义: 对正整数n,欧拉函数是少于或等于n的数中与n互质的数的数目

AC代码:

#include <iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int euler(int n)
{
int res=n;
for(int 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,x,y;
int ans;
scanf("%d",&t);
while(t--)
{
ans=0;
scanf("%d%d",&x,&y);
for(int i=1;i*i<=x;i++)
{
if(x%i==0)
{
if(i>=y) ans+=euler(x/i);//x/i的质因子*i和x的最大公约数为i>y
if(x/i>=y&&x/i!=i) ans+=euler(i);//当i*i==n时只要计算一次
}

}
printf("%d\n",ans);
}

return 0;
}








posted @ 2016-08-04 20:03  踮起脚望天  阅读(163)  评论(0编辑  收藏  举报