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)的所有约数。
#include<cstdio>
#include<cmath>
using namespace std;
typedef long long ll;
ll gcd(ll m,ll n){return n?gcd(n,m%n):m;}//求最小公倍数
ll divisor_num(ll n)//求n得所有约数的个数
{
ll cnt=0;
ll sqrt_n=(ll)sqrt(n);
for(ll i=1;i<=sqrt_n;i++)
{
if(n%i==0)
{
cnt+=2;
if(i*i==n) cnt-=1;
}
}
return cnt;
}
int main()
{
ll N,M,N_cnt,M_cnt;
scanf("%lld%lld",&N,&M);
N_cnt=divisor_num(N);
M_cnt=divisor_num(M);
ll D=gcd(N,M);
ll D_cnt=divisor_num(D);
ll tmp=gcd(N_cnt*M_cnt,D_cnt);
printf("%lld %lld\n",N_cnt*M_cnt/tmp,D_cnt/tmp);
}