拓展欧几里得算法

一、拓展欧几里得算法

1.1 算法简析

根据裴蜀定理,对任意 a a a b b b,一定存在 x x x y y y,使 a x + b y = gcd ( a , b ) ax + by = \text{gcd}(a, b) ax+by=gcd(a,b)。拓展欧几里得算法不仅能求出 a a a b b b 的最大公约数,而且能找到一对 ( x , y ) (x, y) (x,y) 使该方程成立。

设求解 a x + b y = gcd ( a , b ) ax + by = \text{gcd}(a, b) ax+by=gcd(a,b) 的函数为

int extgcd(int a, int b, int &x, int &y)

该函数返回 gcd ( a , b ) \text{gcd}(a, b) gcd(a,b),即 a a a b b b 的最大公约数。同时,引用的 x x x y y y 就是方程的一对解。

假设 b ≠ 0 b \neq 0 b=0
extgcd(a, b, x, y) \text{extgcd(a, b, x, y)} extgcd(a, b, x, y) 表示的方程为 a x + b y = gcd ( a , b ) ax + by = \text{gcd}(a, b) ax+by=gcd(a,b)
extgcd(b, a % b, x’, y’) \text{extgcd(b, a \% b, x', y')} extgcd(b, a % b, x’, y’) 表示的方程为 b x ′ + ( a   %   b ) y ′ = gcd ( b , a   %   b ) bx' + (a~\%~b)y' = \text{gcd}(b, a~\%~b) bx+(a % b)y=gcd(b,a % b)

我们知道 a   %   b a~\%~b a % b 是取余运算,可以转换成 a   %   b = a − ⌊ a b ⌋ × b a~\%~b = a - \lfloor \frac{a}{b} \rfloor \times b a % b=aba×b,代入方程得到 b x ′ + ( a − ⌊ a b ⌋ × b ) y ′ = gcd ( b , a   %   b ) bx' + (a - \lfloor \frac{a}{b} \rfloor \times b)y' = \text{gcd}(b, a~\%~b) bx+(aba×b)y=gcd(b,a % b),整理得到 a y ′ + b ( x ′ − ⌊ a b ⌋ × y ′ ) = gcd ( b , a   %   b ) ay' + b(x' - \lfloor \frac{a}{b} \rfloor \times y') = \text{gcd}(b, a~\%~b) ay+b(xba×y)=gcd(b,a % b)

∵ b ≠ 0 ∴ gcd ( a , b ) = = gcd ( b , a   %   b ) ∴ 两个方程的左式是相等的 a x + b y = a y ′ + b ( x ′ − ⌊ a b ⌋ × y ′ ) ∴ x = y ′ ,   y = x ′ − ⌊ a b ⌋ × y ′ \begin{split} &\because b \neq 0 \\ &\therefore \text{gcd}(a, b) == \text{gcd}(b, a~\%~b) \\ &\therefore 两个方程的左式是相等的 \\ \\ &ax + by = ay' + b(x' - \lfloor \frac{a}{b} \rfloor \times y') \\ &\therefore x=y',~y=x' - \lfloor \frac{a}{b} \rfloor \times y' \end{split} b=0gcd(a,b)==gcd(b,a % b)两个方程的左式是相等的ax+by=ay+b(xba×y)x=y, y=xba×y

假设 b = = 0 b == 0 b==0
extgcd(a, b, x, y) \text{extgcd(a, b, x, y)} extgcd(a, b, x, y) 表示的方程为 a x = gcd ( a , 0 ) = a ax = \text{gcd}(a, 0) = a ax=gcd(a,0)=a,可以得到特解 x = 1 ,   y = 0 x=1,~y=0 x=1, y=0

因此,我们可以采用递归的方式定义函数。

1.2 模板

ll extgcd(ll a, ll b, ll &x, ll &y)
{
	if (b == 0)
	{
		x = 1, y = 0;
		return a;
	}
	
	ll ret = extgcd(b, a % b, y, x);
	y -= (a / b) * x;
	
	return ret;
}

1.3 通解

extgcd(a, b, x, y) \text{extgcd(a, b, x, y)} extgcd(a, b, x, y) 可以得到 ( x 0 , y 0 ) (x_0, y_0) (x0,y0) 这一个特解,通解为

x = x 0 + k b gcd ( a , b ) ,   y = y 0 − k a gcd ( a , b ) x=x_0+k\frac{b}{\text{gcd}(a,b)},~y=y_0-k\frac{a}{\text{gcd}(a,b)} x=x0+kgcd(a,b)b, y=y0kgcd(a,b)a


二、相关题目

2.1 题目描述

P1082 [NOIP2012 提高组] 同余方程

2.2 问题简析

题目要求 a x ≡ 1   ( mod  b ) ax \equiv 1~(\text{mod}~b) ax1 (mod b) 的最小正整数解。因为拓展欧几里得算法求解方程的格式为 a x + b y = gcd ( a , b ) ax + by = \text{gcd}(a, b) ax+by=gcd(a,b),所以要对原式进行转化。

∵ b y ≡ 0   ( mod  b ) ∴ a x + b y ≡ 1   ( mod  b ) 令  a x + b y = 1 由裴蜀定理 ,若该方程有解,则 gcd ( a , b ) = 1 ∴  求  a x + b y = gcd ( a , b )  成立的最小正整数  x \begin{split} &\because by \equiv 0~(\text{mod}~b)\\ &\therefore ax+by \equiv 1~(\text{mod}~b) \\ \\ &令~ax+by=1\\ 由裴蜀定理&,若该方程有解,则~\text{gcd}(a, b) = 1\\ \\ \therefore~求~ax+by&=\text{gcd}(a, b)~成立的最小正整数~x \end{split} 由裴蜀定理  ax+byby0 (mod b)ax+by1 (mod b) ax+by=1,若该方程有解,则 gcd(a,b)=1=gcd(a,b) 成立的最小正整数 x

至此,我们可以直接套用上文的模板求解。需要注意的是,本题要求的是 x x x 的最小正整数解,所以求出 x 0 x_0 x0 后要进行处理:

x = (x % b + b) % b;

2.3 AC代码

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

ll a, b, x, y;

ll extgcd(ll a, ll b, ll &x, ll &y)
{
	if (b == 0)
	{
		x = 1, y = 0;
		return a;
	}
	
	ll ret = extgcd(b, a % b, y, x);
	y -= (a / b) * x;
	
	return ret;
}

int main()
{
	cin >> a >> b;
	extgcd(a, b, x, y);
	cout << (x % b + b) % b << endl;
	
	return 0;	
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值