JinlinOJ 通化邀请赛 E.GCD and LCM 最大公约数最小公倍数 关系

首先我先给出一个他们之间的关系

最大公约数L和最小公倍数G的关系:

1、L%G == 0;

2、设A, B的最大公约数为G, 最小公倍数为L,则:

L/G = (A/G)*(B/G)

3、gcd(A/G, B/G) = 1;

 

本题:

题意:给你三个数x,y,z的最大公约数gcd,最小公倍数lcm . 然后求满足的x,y,z有多少种可能。(1,3,2) 和 (1,2,3)被视为不同

思路:

首先lcm%gcd == 0是必须的,否则无解。然后将tmp = lcm/gcd 进行因式分解。假设其中有一个质因子p1的幂为e1,那么着三个数中至少有一个含有p1,至少有一个不含p1 。如果都含有p1的话他就被分到最大公约数里面去了,不会在tmp里面,如果不含有p1的话,那么p1就一定不会存在了。

那么对于质因子p1来说 如果有两个含有他的话那么结果为A(3,2)*(e1 - 1)  e1 可以分成x ,y (x+y = e1 x!=0 && y != 0)  如果有一个含有它的话那么必定是含有p1^e1次方。如果不是p1^e1次方的话,那么tmp里面的p1的幂也就不是e1了。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
#include <string>
#include <set>
#include <functional>
#include <numeric>
#include <sstream>
#include <stack>
#include <map>
#include <queue>

#define CL(arr, val) memset(arr, val, sizeof(arr))

#define lc l,m,rt<<1
#define rc m + 1,r,rt<<1|1
#define pi acos(-1.0)
#define L(x)    (x) << 1
#define R(x)    (x) << 1 | 1
#define MID(l, r)   (l + r) >> 1
#define Min(x, y)   (x) < (y) ? (x) : (y)
#define Max(x, y)   (x) < (y) ? (y) : (x)
#define E(x)        (1 << (x))
#define iabs(x)     (x) < 0 ? -(x) : (x)
#define OUT(x)  printf("%I64d\n", x)
#define lowbit(x)   (x)&(-x)


#define M 137
#define N 5007
#define ll long long
using namespace std;
const double eps = 1e-10;

int no[N];
ll ans;

int main()
{
//    Read();
    int T,i;
    scanf("%d",&T);
    ll gcd,lcm;
    while (T--)
    {
        cin>>gcd>>lcm;
        if (lcm%gcd != 0) printf("0\n");
        else
        {
            CL(no,0);
            ll tmp = lcm/gcd;
            int len = 0;
            for (i = 2; i*i <= tmp; ++i)
            {
                if (tmp%i == 0)
                {
                    len++;
                    while (tmp%i == 0)
                    {
                        no[len]++;
                        tmp /= i;
                    }
                }
            }
            if (tmp > 1) no[++len] = 1;
            ans = 1;
            for (i = 1; i <= len; ++i)
            {
                ans = ans*(6 + 6*(no[i] - 1));
            }
            cout<<ans<<endl;
        }
    }
    return 0;
}
View Code

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值