欧几里得算法 以及 扩展

欧几里得算法

欧几里得算法(又称:辗转相除法),可以快速求出两个的 最小公倍数

gcd(a,b)={a,(b=0)gcd(b,amodb)

int gcd(int a, int b)
{
	return b==0?a:gcd(b,a%b);
//	whlie (b^=a^=b^=a%=b); return a; 
}

证明:

如果 x|ax|b,则 a=mx,b=nx。所以 ab=mxnx=(mn)x,即 x|ab
相反,如果 x|abx|b,则 ab=mx,b=nx。所以 ab+b=mx+nx=(m+n)x,即 x|a

xab 的公因数,那么我们证明了 (a,b)(ab,b) 的公因数相同。

因为 (a,b)(ab,b) 的公因数相同,(ab,b)(abb,ab) 的公因数相同,所以 (ak×b,b)(a,b) 的公因数相同,(amodb,b)(a,b) 的公因数相同。

因为 gcd(a,0)=a,所以我们有了边界条件。


其他:

(1)由唯一分解定理,可知 a×b=gcd(a,b)×lcm(a,b),   lcm(a,b)=a/gcd(a,b)×b
(2)由于 辗转相除法 与 斐波那契数列 的性质,对两个大的相邻的斐波那契数求最大公倍数是较慢的。(优化辗转相除法)

gcd(a,b) ans=1
1、a,b除以2,直到为奇数为止,记录a,b除以2的次数中较小的那个,记为x。ans*=2^x;
2、新得到的a,b用欧几理德算法。但是每次得到的a%b都要除以2直到为奇数。
3、ans*=b;


扩展欧几里得算法

求解 不定方程 ax+by=c 的一组可行解,用到扩展欧几里得算法。
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, y, x);
	y -= a/b*x;
	return r;
}

证明:

裴蜀定理 可知,ax+by=gcd(a,b),所以当且仅当 cgcd(a,b) 的倍数时,该不定方程才有解。

设:a>b

则有 gcd(a,b)=gcd(b,amodb)

又因为 ax1+by1=gcd(a,b), bx2+(amodb)y2=gcd(b,amodb) 可得

ax1+by1=bx2+(amodb)y2ax1+by1=bx2+(aab×b)y2ax1+by1=ay2+b(x2aby2)

由 恒等定理 可得:x1=y2, y1=x2aby2

特别的,当 b=0x=1,y=0


应用:
(1)解不定方程 ax+by=c,则 x,y 为原方程的一组解,且 |x|+|y| 的值最小。
其他的解为 x+mb,yma,mZ

int BDFC(int a, int b, int c, int &x, int &y)
{
	int d = exgcd(a, b, x, y);
	if (c%d) return -1;
	int k = c/d;
	x *= k, y *= k;
}

(2)求解线性同余方程(同余方程也可以写为不定方程的形式)。
(3)求模意义下的逆元。

posted @   Ciaxin  阅读(40)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示