Problem E: wjw的数学题
Time Limit: 2 Sec Memory Limit: 128 MB[ Submit][ Status][ Web Board]
Description
Wjw recently encountered a mathematical problem .. given two positive integers x and y, how many kinds of schemes (a, b, c) make their gcd = x, lcm = y
Input
First line comes an integer T (T <= 12), telling the number of test cases.
The next T lines, each contains two positive integers, x and y. The all input is guaranteed to be within the "int"
Output
For each test case, print one line with the number of solutions satisfying the conditions above.
Sample Input
2 6 7
2
7 33
Sample Output
72
0
【分析】
题意很简单,让你求任意x,y,z满足他们的gcd是l,lcm是g的方案数。
首先肯定可以直接发现一个问题那就是,如果g%i!=0那么方案数就是0.
因为三个数的最大公约数一定是最小公倍数的因子,这个很容易证明。
那么麻烦的就是怎么求方案数了,首先可以知道,模拟xyz的组成一定是超时的因为数据范围到2^32-1.
那么就需要数学方法去算了,怎么算呢
首先我们可以考虑
三个数的gcd是l,需要满足什么?
显然,我们先把x,y,z分别质因数分解
可以得到
x=q1^p1*q2^p2*q3^p3....
y=q1^pp1*q2^pp2*q3^pp3....
z=q1^ppp1*q2^ppp2*q3^ppp3....
那么,x,y,z的gcd可以表示为
q1^min(p1,pp1,ppp1)*q2^min(p2,pp2,ppp2).....
lcm就是q1^max(p1,pp1,ppp1)*q2^max(p2,pp2,ppp2).....
那么显然我们可以发现的是,我们先假设x=y=z=l,那么进行怎样的变化可以让x,y,z的lcm变成g呢?显然就是对于每个质因数,只要三个数中有一个数的质因数的个数满足max(p,pp,ppp)就可以了,当然不能有数的质因数大于这个max
那么可以发现,我们要让x=y=z=l变化到lcm是g,只要找到g/l这个数每个质因数的个数,然后做一个组合就可以了..
【代码】
#include <stdio.h>
int prime[1000000];
int f[10000000]={0};
int len=0;
void init()
{
for (int i=2;i<10000000;i++)
if (!f[i])
{
prime[len++]=i;
for (int j=i+i;j<10000000;j+=i)
f[j]=1;
}
}
int main()
{
init();
// for (int i=0;i<10;i++) printf("%d ",prime[i]);
int pp;scanf("%d",&pp);
int l,g;
while (pp--)
{
scanf("%d%d",&l,&g);
if (g%l!=0)
{
printf("0\n");
continue;
}
g/=l;
int ans=1;
for (int i=0;prime[i]<=g;i++)
if (g%prime[i]==0)
{
int t=0;
while (g%prime[i]==0)
{
g/=prime[i];
t++;
}
ans=ans*t*6;
}
printf("%d\n",ans);
}
return 0;
}