D—GCD (HDU 2588)

简介:

传送门


GCD

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1438    Accepted Submission(s): 673


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
 

题目大意:

给定T组数据,然后两个数 N和 M, 让你求1<=X<=N ,GCD (X,N)>=M,让你X的个数


解题思路:

假设 GCD(X,N) = d,那么 X = q * d , N = p * d,而且p 和 q 肯定是互素的,如果d >= M的话,我们要求的只是在 <=p的情况下与 p 互素的个数,然后累加 ,就是假设 N的约数 i >= M,就是求与 <= N/i中与 N/i的个数,也就是求一个欧拉函数,所以这个题就是相当于 欧拉函数的延伸,还是比较不错的,当知道这个之后就是从 1 - N 中找,但是这样还是会超时的,所以我们就从 sqrt(N)中找 ,N%i == 0 和 N%(N/i) ==0,最后特判一下是不是完全平方数就ok了,剩下的就是敲代码了:

My Code:

#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
int Eular(int m)
{
    int ret = m;
    for(int i=2; i*i<=m; i++)
    {
        if(m%i == 0)
        {
            ret -= ret/i;
            while(m%i == 0)
                m /= i;
        }
    }
    if(m > 1)
        ret -= ret/m;
    return ret;
}
int main()
{
    int T, m, n;
    cin>>T;
    while(T--)
    {
        cin>>n>>m;
        int sum = 0;
        for(int i=1; i*i<n; i++)///这样比较省时间
        {
            if(n%i == 0)///n的约数
            {
                if(i >= m)
                {
                    sum += Eular(n/i);
                }
                if(n/i >= m)
                    sum += Eular(i);
            }
        }
        if((int)sqrt(n)>=m)///特判
        {
            if((int)sqrt(n)*(int)sqrt(n) == n)
                sum += Eular((int)sqrt(n));
        }
        cout<<sum<<endl;
    }
    return 0;
}




目录
相关文章
|
算法
HDOJ(HDU) 2504 又见GCD(利用最大公约数反推)
HDOJ(HDU) 2504 又见GCD(利用最大公约数反推)
106 0
|
机器学习/深度学习
POJ 1775 (ZOJ 2358) Sum of Factorials
POJ 1775 (ZOJ 2358) Sum of Factorials
146 0
|
Java
HDU 2504 又见GCD(最大公约数与最小公倍数变形题)
又见GCD Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 18480    Accepted Submission(s): 7708 ...
1180 0