拓展欧几里得求方程整数解和逆元

什么是拓展欧几里得?
所谓拓展,就是在欧几里得的基础上得出的推论。
拓展欧几里得就是根据欧几里得的原理(辗转相除),可以算出二元一次方程组的整数解乘法逆元

拓展欧几里得求方程解:
ax + by = c
我们知道这个方程组在实数范围内是有无数个解的。
但是在整数的范围内他却存在着有限个解。
首先介绍裴蜀定理
这里再证明一下:
为什么在整数解的情况下,c一定是gcd(a,b)的倍数呢?
例:
2 * x + 4 * y = c
那么c无论如何都是偶数,换句话来说,c一定是2的倍数2 = gcd(2,4)

3 * x + 9 * y = c
那么同理c一定是3的倍数,因为上述等于 : 3 * x + 3 * 3 * y = c
3 * (x + 3 * y) = c,外面乘了个3,那么c再怎么都是3的倍数,3 = gcd(3,9)

那么按此方法可以依次类推下去,所以c = gcd(a,b)在有整数解的情况下

那么我们知道了这个,怎么来求得其所有的整数解呢?
借用下大佬的图片
在这里插入图片描述
由特解可以推出通解的形式
在这里插入图片描述
其中t为任意正整数,gcd为a,b的最大公因数,x0,和y0为特解
模板代码:

int ex_gcd(int a,int b,int &x,int &y)
{
    if(b == 0)
    {
        x = 1;
        y = 0;
        return a;
    }
    int d = ex_gcd(b,a%b,x,y);
    int t = x;
    x = y;
    y = t - (a/b)*y;
    return d;
}

返回值是gcd(a,b),x,y最后的返回值是特解

这样就可以根据特解求出通解公式

拓展欧几里得求逆元
我们知道逆元有定义等式:
a * x ≡ 1(mod p) 其中x为逆元,p为模数

那么上述等式可以化成方程:
a * x + p * y = 1

那么利用拓展欧几里得求其一组解,其实也就求得了其逆元x

但是这里得有个前提,如果返回的a,p的最大公因数不为1,那么就不存在逆元,也就是无解

模板代码

int ex_gcd(int a,int b,int &x,int &y)
{
    if(b == 0)
    {
        x = 1;
        y = 0;
        return a;
    }
    int d = ex_gcd(b,a%b,x,y);
    int t = x;
    x = y;
    y = t - (a/b)*y;
    return d;
}
int Inv(int a,int mod) //求a在mod下的逆元,不存在逆元返回-1
{
	int x, y;
	int d = ex_gcd(a, mod, x, y);
	return d == 1 ? (x % mod + mod) % mod : -1; //x可能是负数,转化成正数
}

猜你喜欢

转载自blog.csdn.net/moasad/article/details/107472883