拓展GCD及其应用

参考博客:

            欧几里得算法相关证明


拓展欧几里得算法

基本算法:

对于不完全为0的非负整数a,b,必定存在整数对,x,y使得方程  ax + by = gcd(a,b)成立。

证明:

设 ax1 + by1 =gcd(a,b);-------- “式1”

    bx2 + (a mod b)y2 = gcd(b,a mod b); ---------“式2”

由 gcd(a,b) =   gcd(b,a mod b) 得:

    ax1 + by1  =  bx2 + (a mod b)y2

由 a mod b =   a - (a/b) * b 得:

    ax1 + by1  =  bx2 + [a - (a/b) * b]y2

    ax1 + by1  =  ay2 + b[x2 - (a/b) y2]

由恒等式得:

    x1 = y2

    y1 = x2 - (a/b)y2

当 b = 0 时 gcd(a,b) = a

此时 x = 1,y 为任意值,为得到最小解 y 取 0;


算法实现:
int exgcd(int a,int b,int &x,int &y)
{
	if(b == 0)
	{
		x = 1;
		y = 0;
		return a;
	}
	int r = exgcd(b,a%b,x,y);
	int t = x;
	x = y;
	y = t - (a/b)*y;
	return r;
}

拓展GCD的应用

应用1:求解不定方程:

/*
求解线性方程 ax + by = c
*/
bool linear_equation(int a,int b,int c,int x,int y)
{
	int d = exgcd(a,b,x,y);
	if(c % d)
		return false; // c不为gcd(a,b)的整数倍时,方程无解 
	int k = c / d;
	x = k * x; 
	y = k * y;
	return true; // 其中一组解 
}
/*
通解公式为:
x = x1 + b/gcd(a,b) * t;
y = y1 - a/gcd(a,b) * t; 
t为任意整数
c != gcd(a,b)时,还要乘上k 
*/ 

应用2:求解模线性方程:

引理:

同余方程 ax≡b (mod n)对于未知数 x 有解,当且仅当 gcd(a,n) | b。且方程有解时,方程有 gcd(a,n) 个解。

即相当于求解方程 ax + ny = b;

设 d = gcd(a,b); 则有 ax1 + ny1 = d;

方程两边同乘 (b/d) 得:

a(a/b)x1 + b(a/b)y1 = b;

由恒等式得:

x = (a/b)x1;

y = (a/b)y1;

则同余方程 ax≡b (mod n)一组解为:

x0 = x(a/b) mod n;


设ans=x*(b/d),s=n/d;

方程ax≡b (mod n)的最小整数解为:(ans%s+s)%s;

算法实现:
/*
求解同余方程 ax ≡b(mod n)
*/ 
bool modular_linear_equation(int a,int b,int n)
{
	int x,y,x0,y0;
	int d = exgcd(a,n,x,y);
	if(b%d != 0)
		return false; //b不能整除gcd(a,n)时,方程无解 
	x0 = x * (b/d) % n; //其中一组解 
	return true;
}
/*
通解公式为:
x = (x0 + (n/d)*t) mod n;
t 为任意正整数; 
*/ 

应用3:求模的逆元

同余方程ax≡b (mod n),如果 gcd(a,n)== 1,则方程只有唯一解。

在这种情况下,如果 b== 1,同余方程就是 ax=1 (mod n ),gcd(a,n)= 1。

这时称求出的 x 为 a 的对模 n 乘法的逆元。 

即gcd(a,n) = 1时; 求解方程ax + ny = 1;中的 x 即为 a 对模n的逆元


算法实现:
//  求逆元 ax = 1(mod n)
int modReverse(int a, int n)
{
    int x, y;
    int d = exgcd(a, n, x, y);
    if (d == 1)
    {
        return (x % n + n) % n;
    }
    else
    {
        return -1;  //  无逆元
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值