N有N_cnt个约数,M有M_cnt个约数,那么总共有N_cnt * M_cnt种对应情况。
假设其中有D_cnt个对应结果是相等的,而这D_cnt个数正好是gcd(N,M)的所有约数。
例如:
N=18 , M=42
18 = 1 * 18 ; 2 * 9 ; 3 * 6 ; N_cnt=6
42 = 1 * 42 ; 2 * 21 ; 3 * 14 ; 6 * 7 ; M_cnt=8
其中 1、2、3、6是相等的情况,
而gcd(18,42) = 6 = 1 * 6 ; 2 * 3 ;
就是gcd(N,M)的所有约数。
1 #include<cstdio> 2 #include<cmath> 3 using namespace std; 4 typedef long long ll; 5 ll gcd(ll m,ll n){return n?gcd(n,m%n):m;}//求最小公倍数 6 ll divisor_num(ll n)//求n得所有约数的个数 7 { 8 ll cnt=0; 9 ll sqrt_n=(ll)sqrt(n); 10 for(ll i=1;i<=sqrt_n;i++) 11 { 12 if(n%i==0) 13 { 14 cnt+=2; 15 if(i*i==n) cnt-=1; 16 } 17 } 18 return cnt; 19 } 20 int main() 21 { 22 ll N,M,N_cnt,M_cnt; 23 scanf("%lld%lld",&N,&M); 24 N_cnt=divisor_num(N); 25 M_cnt=divisor_num(M); 26 ll D=gcd(N,M); 27 ll D_cnt=divisor_num(D); 28 ll tmp=gcd(N_cnt*M_cnt,D_cnt); 29 printf("%lld %lld ",N_cnt*M_cnt/tmp,D_cnt/tmp); 30 }