#include <iostream>
#include <algorithm>
#include <cmath>
#include <string.h>
using namespace std;
int main(){
int t;
scanf("%d",&t);
while(t--){
int g,l;
scanf("%d%d",&g,&l);
if(l%g) { //互质时不能取到符合题意的数字
printf("%d\n",0);
continue;
}
int n=l/g;
int ans=1;
for(int i=2;i<=n;i++){ //跳出循环的条件判定不是sqrt(n)
int temp=0;
if(n%i==0){
while(n%i==0){
temp++; <span style="font-family: Arial, Helvetica, sans-serif;">//统计每个因子的个数</span>
n/=i;
}
ans*=6*temp; //某个因子统计完后直接乘起来
}
}
printf("%d\n",ans);
}
}
GCD性质的运用与简单的计数原理。
根据唯一分解定理每个x,y,z都可以分成素数幂形式;
x=p1^x1*p2^x2*…pn^xn;
y=p1^y1*p2^y2*…pn^yn;
z=p1^z1*p2^z2*…pn^zn;
g=gcd(x,y,z)=p1^min(x1,y1,z1)*…pn^min(xn,yn,zn);
l=lcm(x,y,z)=p1^max(x1,y1,z1)*…pn^max(xn,yn,zn);
如果l不能被g整除 则它们没有相同因子 返回0;
如果能整除 则它们的商我们可以用来分解到不同情况 然后进行排列组合;
e.g.对于6 72
正常思路是:
对于素数2:
分配上限是72的3个2 下限是6的1个2;
则它的分配可以为2 8 8 | 2 2 8 | -任意排列组合有6种
也可以为2 4 8 -任意排列组合有6种
它分配给xyz可以有12种分法
对于素数3:
分配上限是72的2个3,下限是6的1个3
3 3 6 | 3 6 6|-任意组合排列有6种
它分配给xyz可以有6种分法
各个素数的分法相乘即为总数;
但是我们可以直接用72/6=12=2^2*3来做
相当于x/g,y/g,z/g的下限都为0,上限为12的某个素数的幂;
对于2:0 0 4 | 0 4 0 -6种
0 2 4 -6种
对于3:0 1 0 | 0 1 1 -6种
即各素数幂ai*6后累乘;
1.注意分解时的判定条件,直接用sqrt(n)易错 因为已经改变了n的值,之前的分解质因子不会错是因为在n最后一个因子直接储存了,这里可以把判定条件改为 i<=sqrt(l/g) i<=n或者在最后加上if(n!=1)ans*=6; 都可以。
2.这里的代码主要就是分解质因子时的统计,这里务必要注意,不要直接拿以前分解质因子的代码copy,应根据不同情况作出相应修改。
参考文章:http://blog.csdn.net/u013532224/article/details/45604761