【数学】EXGCD

\(\rm EXGCD\),即 扩展欧几里得算法,简称 扩欧,是用来求出方程

\[ax+by=\gcd(a,b) \]

的整数解的,其中 \(a,b\) 均为整数.

前置芝士:辗转相除法裴蜀定理

我们考虑辗转相除法的最后一步,当 \(b=0\) 时,要使得

\[ax+0y=\gcd(a,0)=a \]

成立,那么只要取 \(x=1\),\(y\) 取任意整数即可,不妨取 \(y=0\).

因为 \(\gcd(a,b)=\gcd(b,a\bmod b)\),所以可以考虑当整数 \(x,y\) 使得

\[bx+(a\bmod b)y=\gcd(b,a\bmod b) \]

成立时,如何推出使得

\[ax'+by'=\gcd(a,b) \]

成立的 \(x',y'\).

对于 \(bx+(a\bmod b)y=\gcd(b,a\bmod b)\),

\(\begin{aligned}等式左边&=bx+(a-b\left\lfloor\frac{a}{b}\right\rfloor)y\\&=ay+b(x-\left\lfloor\frac{a}{b}\right\rfloor y)\end{aligned}\)

\(\begin{aligned}等式右边&=\gcd(a,b)\end{aligned}\)

所以要使 \(ax'+by'=\gcd(a,b)\) 的话,取 \(x'=y,y'=x-\left\lfloor\frac{a}{b}\right\rfloor y\) 即可。

就这样一直递归。

\(\text{Code}\)

int x, y;

void exgcd(int a, int b)
{
	if (!b)
	{
		x = 1, y = 0;
		return;
	}
	exgcd(b, a % b);
	ll tmp = x; //先将 x 存下来
	x = y;
	y = tmp - a / b * y;
}
上一篇:AcWing 第21场周赛 最大公约数


下一篇:P1965 [NOIP2013 提高组] 转圈游戏