GCD与LCM


一、GCD

1.定义

最大公因数(Greatest Common Divisor, GCD),指
两个或多个整数共有约数中最大的一个。

2.欧几里得算法(辗转相除法)

运算中有取模操作,不管是用递归写法,还是循环写法,对执行次数影响不大,所以整体可以控制在一个接近常数时间内完成。

int gcd(int a,int b){
	return b?gcd(b,a%b):a;
}

3.辗转相除法简单证明

目标:证明GCD(a,b)==GCD(b,a%b)

1.证明 GCD(a,b) 是 b,a%b 的一个公约数
2.证明 GCD(a,b) 是 b,a%b 的最大的公约数
在这里插入图片描述

2.大数计算GCD优化

在这里插入图片描述


二、LCM

1.定义

两个或多个整数公有的倍数称为它们的公倍数,其
中除0 以外最小的一个公倍数是这些整数的 最小公
倍数。

2.LCM与GCD联系

在这里插入图片描述

三、LCM Walk

LCM Walk

1.分析

终点为(ex,ey),我们设前一个点为(x,y)
令t=GCD(x,y)
x=pt;
y=qt;
则LCM(x,y)== x * y / t == p * q * t
而且作为最小公倍数,必定有LCM(x,y)>=max(x,y)
所以不管哪一方加上最小公倍数,ex,ey都会有大小区别,而且那个较大项就是进行了处理的位置

若ex < ey,
说明
ex=x=p * t;
ey=y+LCM(x,y)= q * (1+p)* t;
根据辗转相除法可知 p 与(1+p)为互质关系,而 p 、q 就是互质关系,
所以:
GCD(ex,ey)== GCD(x,y)== t

此时,x就等于ex,
y == ey - LCM(x,y) == ey - p * t * q == ey - ex * q == ey - ex * ey /(t+ex)
==(ey * t)/(ex + t)

由此我们就可以直接从(ex,ey)得到(x,y)。
但我们需要y为一个整数,才能找到一个准确的点,所以此时若y%(x+t)!=0时,将无法逆推,即不存在满足要求的点。

//终点也可以视作一步未走的起点。

2.代码

#include<iostream>
#include<algorithm>
using namespace std;
int gcd(int a,int b){
	return b?gcd(b,a%b):a;
}
int main(){
    int x,y,T;
    cin>>T;
    for(int i=1;i<=T;i++){
        cin>>x>>y;
        if(x<y) swap(x,y);
        int k=gcd(x,y),cnt=1;
        while(x%(y+k)==0){
            cnt++;
            x=x/(y/k+1);
            if(x<y) swap(x,y);
        }
        printf("Case #%d: %d\n",i,cnt);
    }
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值