扩展欧几里得

问题描述

对于三个整数 a, b , c. 求解 \(ax+by=c\) 的( x , y )的整数解。

推导过程

首先我们要判断是否存在解,对于这个这个存在整数解的充分条件是 c 是 gcd(x,y) 的倍数。

朴素欧几里得

对于求解 gcd(x,y) 我们需要用 朴素欧几里得定理 。

gcd(a,b)=gcd(b,a%b).

这个比较好证明。

假设\(a=k\times b+r\) ,有r=a mod b,不妨设 d 为 a 和 b 的一个任意一个公约数,则有a ≡ b ≡ 0 ( mod d).

由于同余的性质 \(a-k\times b\)≡ r ≡ 0 (mod d)。因此 d 是 b 和 a mod b 的公约数。

然后任意一个公约数都满足,所以这个定理成立。

代码:

int gcd(int x,int y)
{
    if(y==0)
        return x;
    else
        return gcd(y,x%y);
}

这个复杂度是 O(log) 的,十分迅速。


然后判定是否有解后,我们需要在这个基础上求一组解 (x,y),由于 a,b,c 都是 gcd (a,b) 的倍数。

对于 a,b 有负数的情况,我们需要将他们其中一个负数加上另外一个数直到非负。(由于前面朴素欧几里得定理是不会影响的)两个负数,直接将整个式子反号,然后放到 c上就行了。

我们将它们都除以 gcd (a,b),不影响后面的计算。

也就是我们先求对于 ax+by=1且 (a和 b互质)求 (x,y) 的解。

接下来我们利用前面的朴素欧几里得定律推一波式子。

**\(ax+by=gcd(a,b)\) **

\(=gcd(b,a mod b)\)

可得 bx+(a mod b)y=bx+(a-[\(\frac{a}{b}\)]b)y

\(= ay+b(x-[\frac{a}{b}]y)\)

不难发现此时 x 变成了 y , y 变成了 x−⌊a/b⌋ y,利用这个性质,我们可以递归的去求解 (x,y) 。

边界条件其实和前面朴素欧几里得是一样的b=0 的时候,我们有 a=1,ax+by=1 那么此时x=1,y=0 。

这样做完的话我们用 O(log) 的时间就会得到一组 (x,y) 的特殊解。

解系扩展

**注意:这里的\(x_0\)\(y_0\)\(ax+by=gcd(a,b)\) 的一组特殊解 **

通解是(d是整数)\(x=x_0+db\) \(y=y_0-da\)

代码:

代码说明,现根据普通欧几里得算法逐步深入到最底层(b=0),在一步一步回归

//求ax+by=gcd(a,b)的特解x,y
int exgcd(int a, int b, int& x, int& y)
{
	if (b == 0)
    {
		x = 1, 
        y = 0;
		return a;
	}
	int q = exgcd(b, a % b, y, x);
	y -= a / b * x;
	return q;
}

要想求\(ax+by=c\)的解:

注意int相乘越界
只要将\(ax+by=gcd(a,b)\) 的一组特解\(x_0\),\(y_0\)做如下变化:

\(x_1=x_0 \times c \div gcd(a,b)\)

\(y_1=y_0 \times c \div gcd(a,b)\)

\(x_1,y_1\)即为\(ax+by=c\)一组特解。

\(ax+by=c\)的通解:

(d是整数)\(b_1=b \div gcd(a,b)\) , \(a_1=a \div gcd(a,b)\)

\(x=x_1+db_1\)

\(y=y_1-da_1\)

求解同余方程

求关于x的同余方程\(ax\) ≡ c (mod b) 的最小正整数解。

上式可以转化成\(ax+by=c\)

\(x,y\)是一组特解,

最小正整数解:
x>0时,x需要减小许多b从而达到最小正整数解,即x=x%b;
x<0时,x需要加上许多b从而达到最小正整数解,即x=x%b+b
综合起来:
x = (x % b + b) % b;
posted on 2021-11-28 16:11  naiji  阅读(42)  评论(0)    收藏  举报