hdu

来源:互联网 发布:js设置select不可用 编辑:程序博客网 时间:2024/06/11 01:12

题目描述

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.

输入

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.

输出

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

样例输入

3
1 1
10 2
10000 72

样例输出

1
6
260

补充知识 - GCD原理

  • 如果GCD(a,b)=c,则可以知道GCD(a/c,b/c)=1;( GCD(a,b)=c <=> GCD(a/c,b/c)=1 )
  • 设GCD(a,b)=c,如果想要GCD(a,b*d)=c,由上可知,只需满足GCD(a/c,(b/c)*d)=1即可(这个限制既为,满足最大公约数的要求).

题解

  • 先分析GCD(N,X)≡c,我们可以转化为GCD(N/c,X/c)=1,即互质个数。
  • 当M=1时,直接调用欧拉函数Euler。
  • 当M≥2时,因为GCD(N,X)=c,其中c≥M,X∈[1,N],由上GCD原理知,只要GCD(N/c,X/c)=1即可,而我们知道GCD(N,X)=c,c是最大公约数其实就是N的所有因子。
  • 所以我们只要枚举一遍大于等于M的N的因子c,对euler(c)累加和即可。
  • 举个例子:N=12,M=3。N大于等于3的因子有3、4、6、12。根据刚刚说的,我们要求c=3、4、6、12,即可转化为GCD(N/c,X/c)=1互质个数。好了,看代码。
#include<cstdio>#include<cmath>#include<iostream>using namespace std;int Euler(int n){//欧拉函数    int m=sqrt(n+0.5);    int res=n;    for(int i=2;i<=m;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;    scanf("%d",&T);    while(T--){        int N,M;        scanf("%d%d",&N,&M);        int ans=0;        for(int i=1;i*i<=N;i++){            if(N%i==0){                if(i>=M) ans+=Euler(N/i);                if(N/i>=M&&N/i!=i) ans+=Euler(i);            }        }        printf("%d\n",ans);    }}
原创粉丝点击