HDU 2588 GCD(欧拉函数)

GCD


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


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


题解:对于gcd(x,n)>=m;设gcd(a,b)=1,x=a*i,n=b*i,gcd(x,n)=i>=m,b=n/i,只需求小于等于b的与b互质的数的个数(也就是eular(b));

#include<iostream>
#include<algorithm>
#include<string.h>
#define ll long long
using namespace std;
ll eular(ll n)//欧拉函数模板
{
        ll res=n;
        for(ll i=2;i<=n;i++){
                if(n%i==0){
                        res=res/i*(i-1);//p^i-p^(i-1)
                        while(n%i==0)
                                n/=i;
                }
        }
        return n>1?res/n*(n-1):res;//最后不为1的情况
}
int main()
{
        int T;
        ll N,M;
        scanf("%d",&T);
        while(T--){
                ll ans=0;
                scanf("%lld%lld",&N,&M);
                for(ll i=1;i*i<=N;i++){
                        if(!(N%i)){
                                if(i>=M)
                                        ans+=eular(N/i);//gcd(x,m)=i>=m;
                                if(i*i!=N&&N/i>=M)//gcd(x,m)=n/i>=m;
                                        ans+=eular(i);//i=N/(N/i);
                        }
                }
                printf("%lld\n",ans);
        }
        return 0;
}

 

posted @ 2018-12-24 19:32  aeipyuan  阅读(135)  评论(0编辑  收藏  举报