VJ链接
题意:给出你两个数g和l。问有多少有序数组(x,y,z)满足gcd(x,y,z)=g,lcm(x,y,z)=l
思路:
1.对于(a,b,c),g和l必然存在l%g=0,因为三个数可以写成:a=x1gcd, b=x2gcd, c=x3gcd; l=ab*c/gcd; 显而易见,l%g=0若l%g!=0,不存在满足题意的情况。
2. 由于l%g==0,问题等价于求三个互质的数且LCM为l/g的所有情况数。
3.对2~n的数进行质因数分解,开一个数组存一下每个质因子的个数。对于:temp=l/g=p1 ^a1 * p2 ^a2 *p3 ^a3… * pn ^an
存在:
a=p1 ^ ai * p2 ^ ai *p3 ^ai… * pn ^ai
b=p1 ^ aj * p2 ^ aj *p3 ^aj… * pn ^aj
c=p1 ^ ak * p2 ^ ak *p3 ^ ak… * pn ^ak
最终推导规律:sum=a1 6a2 * 6 *…an * 6
代码:`
#include<stdio.h>
#include<string.h>
#define N 1000010
int a[N],k;
int main()
{
int t,n,m;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
if(m%n){ //如果m%n!=0,数据不对
printf("0\n");
continue;
}
int l=m/n,s=1,k=0;
memset(a,0,sizeof(a));
for(int i=2;i<=m/n;i++)
if(l%i==0){
while(l%i==0)
a[k]++,l/=i; //记录质因子个数
k++;
}
if(l>1) a[k++]++; //剩余了一个质数
for(int i=0;i<k;i++)
if(a[i])
s*=a[i]*6; //推导的规律
printf("%d\n",s);
}
return 0;
}