欧几里得及扩展欧几里算法

欧几里得:

实际上就是辗转相除法求最大公约数。

给定一个a,b,求他们的最大公约数(gcd)

辗转相除法是:(一般a>b)

gcd(a,b)

第一轮:a%b=a2a\%b=a_2a%b=a2

此时gcd(b,a2a_2a2)

第二轮:b%a2=a3b\%a_2=a_3b%a2=a3

直到gcd(x,0),答案为x.

举例:

gcd(48, 18)

48 ÷ 18 = 2 余 12 → gcd(18, 12)

18 ÷ 12 = 1 余 6 → gcd(12, 6)

12 ÷ 6 = 2 余 0 → gcd(6, 0)

b=0 → 结果 = 6

代码:

cpp 复制代码
int gcd(int a,int b)
{
    if(b)
        return gcd(b,a%b);
    else 
        return a;
}

扩展欧几里得:

简单来说就是带记录的欧几里得。

形如:ax+by=gcd(a,b)ax + by = gcd(a ,b)ax+by=gcd(a,b)

计算gcd的同时,会记录出对应的(x ,y);

由欧几里得可知:
gcd(a,b)=gcd(b,a%b)gcd(a,b)=gcd(b ,a\%b)gcd(a,b)=gcd(b,a%b)

由整除法可得:
a%b=a−⌊a/b⌋∗ba\%b=a - \lfloor a/b \rfloor*ba%b=a−⌊a/b⌋∗b

带入上式,整理可得:
ay1+b(x1−⌊a/b⌋∗y1)=gcd(a,b)ay_1 +b(x_1 - \lfloor a/b \rfloor * y_1) = gcd(a,b)ay1+b(x1−⌊a/b⌋∗y1)=gcd(a,b)

联立原式:
x=y1y=x1−⌊a/b⌋∗y1x=y1\quad y=x_1-\lfloor a/b \rfloor*y_1x=y1y=x1−⌊a/b⌋∗y1
当b==0时:
x=1y=0x=1\quad y=0x=1y=0

代码:

cpp 复制代码
int exgcd(int a,int b,int &x,int &y)
{
	if(b==0){
		x=1,y=0;
		return a;
	}
	int x1,y1;
	int d=exgcd(b,a%b,x1,y1);
	x=y1;
	y=x1-(a/b)*y1;
}

exgcd(b,a%b,y,x)exgcd(b, a\%b, y, x)exgcd(b,a%b,y,x)调用时,y 接收了递归的 x1,x 接收了递归的 y1

然后只需要 y−=a/b∗xy -= a/b * xy−=a/b∗x就完成了 y=x1−(a/b)∗y1y = x1 - (a/b)*y1y=x1−(a/b)∗y1

整理简化得:

cpp 复制代码
int exgcd(int a,int b,int &x,int &y)
{
    if(!b){
        x=1,y=0;
        return a;
    }
    
    int d=exgcd(b,a%b,y,x);
    y-=a/b*x;
}
相关推荐
XMAIPC_Robot6 小时前
国产FPGA替代Xilinx在储能电力采集场景可行性评估与移植经验
人工智能·算法·机器学习·fpga开发·rk3588+fpga
开开心心就好6 小时前
一元二次方程求解工具,答案带详细步骤
java·服务器·开发语言·算法·pdf·ocr·perl
Logic1016 小时前
C语言/数据结构位运算题解:异或XOR找出套碗游戏中的“幸运碗“——只出现一次的数字
c语言·数据结构·算法·数组·位运算·时间复杂度·空间复杂度
yi0117 小时前
LeetCode 3. 无重复字符的最长子串|不定长滑动窗口:什么时候更新最大值?
笔记·python·算法·leetcode·双指针·滑动窗口
y1su7 小时前
Leetcode 单调栈模板
java·开发语言·数据结构·算法·leetcode
索尔~古德曼7 小时前
CF(1400-1400&1300-1500)
算法
一只旭宝7 小时前
树的家族全景:从二叉树到 B+ 树
数据结构
爱刷碗的苏泓舒7 小时前
泰勒级数与泰勒展开:GNSS卫地距线性化、Jacobian矩阵与Hessian矩阵
线性代数·算法·矩阵·gnss·雅可比矩阵·卫地距线性化·海森矩阵
垆边人似月.7 小时前
华为题:每日温度
数据结构·c++·算法
Sylvia-girl7 小时前
堆排序算法
算法·排序算法·c