ZCMU—1796

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;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值