拓展欧几里得算法

1.拓展欧几里得
适用于解决:给定两个非零整数 a 和 b,求一组整数解( x,y ),使得 ax + by = gcd(a , b)成立,其中 gcd(a,b) 表示 a,b 的最大公因数。

求解ax+by=gcd(a,b)的一组特解x0,y0,并返回gcd(a,b)。
代码实现:
一般:

int exgcd(int a,int b,int &x,int &y){
	if(b==0){
		x = 1;
		y = 0;
		return a;
	}
	
	int g = exgcd(b,a%b,x,y);
	int temp = x;
	x = y;
	y = temp - a / b * y;
	return g;
} 

简洁实现:

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

2.方程 ax + by = c 的求解
方程有解的充要条件是 c % gcd(a, b)== 0。
其通解表示为:
x = c * x0 / gcd + b / gcd * k;
y = c * y0 / gcd - a / gcd * k;
k为任意整数。
x的最小整数解:

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

y的最小整数解:

y=(y % (a / gcd) + (a / gcd) ) % (a / gcd);

3.同余式 ax ≡ c(mod m) 求解
ax ≡ c(mod m) <–> (ax - c) % m = 0

根据同余式的定义,有(ax - c)%m = 0成立,因此存在整数 y,使得 ax - c = my成立。
移项并令y = -y 然后得到 ax + my = c.

设a,c,m 是整数,其中 m ≥ 1,则:

  • [1] 若c % gcd(a,m) ≠ 0,则同余式 ax ≡ c(mod m) 无解
  • [2] 若c % gcd(a,m) = 0,则同余式 ax ≡ c(mod m) 恰好有gcd(a,m)个模m意义下不同的解,且解的形式为 x‵ = x + m / gcd(a,m) * k;
    其中 k = 0,1,……gcd(a,m)-1,x 是 ax + my = c 的一个解。
    4.逆元的求解以及(b/a)%m 的计算
    假设a,b,m是整数,m>1,且有ab ≡ 1(mod m)成立,那么就说a和b互为模m的逆元。
    通俗地讲,如果两个整数的乘积模m后等于1,就称这它们互为m的逆元。
    有定义知:求a模m的逆元,就是求解同余式ax ≡ c(mod m),并且**在实际使用中,一般把x的最小正整数解称之为a模m的逆元,因此下文提到的逆元默认为x的最小正整数解。显然,同余式 ax ≡ c(mod m) 是否有解取决于1%gcd(a,m)是否为0,而这等价于gcd(a,m)是否为1:
  • [1] 如果gcd(a,m)≠1,那么ax ≡ c(mod m)无解,a不存在模m的逆元。
  • [2] 如果gcd(a,m)=1,那么ax ≡ c(mod m)在(0,m)上有唯一解。
int inverse(int a,int m){
	int x,y;
	int g = exgcd(a,m,x,y);		//求解ax + by = 1
	return (x % m + m) % m;		//a模m的逆元为(x%m+m)% m	
}

如果m是素数,且a不是m的倍数,可以用费马小定理来的逆元,
费马小定理:设m是素数,a是任意整数且 a mod m ≠ 0,则有 am-1 ≡ 1(mod m)
所以a * am-2 ≡ 1(mod m),即 am-2%m 是 a 模 m的逆元
假设(b / a)% m = x,因此存在整数 k,使得b / a = km + x。等式两边同时乘以 a,得 b = kam + ax,于是b%(am) = ax。等式两边同时除于 a,得(b % (am)) / a = x,于是有(b / a) % m = (b%(am))/a成立。
因此在 a 和 m 有可能互补相素的情况下,可以使用公式(b / a) % m = (b % (am) ) / a来计算(b/a)%m的值,唯一注意的的是a和m的乘积可能会太大而溢出。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

逃夭丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值