欧几里得算法
是什么?
欧几里得发明的算法.
有啥用?
求解两个数的 \(\gcd\).
内容?
怎么证?
不妨设 \(a \gt b\).
\(a = kb + r\), 则 \(a \% b = r\).
设 \(a,\ b\) 的公约数为 \(d\), 则有 \(d \mid a, \ d\mid b\).
因为 \(r = a \% b = a - kb\), 所以 \(r\div d = (a-kb) \div d = a \div d - kb \div d\),
于是 \(d \mid r\).
所以 \(a,\ b\) 的公约数一定是 \(b, \ r\) 的公约数,
因此 \(\gcd(a,\ b) = \gcd(b,\ r)\),
即 \(\gcd(a,\ b) = \gcd(b,\ a\%b)\).
若 \(a \lt b\), 进行一次操作后就可以转化为上述 \(a \gt b\) 的形式.
怎么写?
int gcd(int a, int b){
if(!b){
return a;
}
return gcd(b, a%b);
}
ExGCD
是什么?
顾名思义, 就是 Extended GCD.
有啥用?
常用于求 \(ax + by = \gcd(a,\ b)\) 的一组可行解.
\(a,\ b\) 均为整数, 而非均为正整数.
怎么搞?
上式要有整数解, 显然需要满足 \(a,\ b\) 不同时为 \(0\) ( 裴蜀定理 )
设:
\(ax_1 + by_1 = \gcd(a,\ b) \\ bx_2 + a\%b y_2 = \gcd(b,\ a\%b)\)
根据欧几里得算法, 我们有: \(\gcd(a,\ b) = \gcd(b,\ a\%b)\)
所以: \(ax_1 + by_1 = bx_2 + a\%b y_2\)
又: \(a\%b = a - \lfloor\frac{a}{b}\rfloor\cdot b\)
所以: \(ax_1 + by_1 = bx_2 + (a - \lfloor\frac{a}{b}\rfloor\cdot b) y_2\)
整理, 得: $ax_1 + by_1 = ay_2 + b(x_2 - \lfloor\frac{a}{b}\rfloor y_2) $
所以 \(x_1 = y_2,\ y_1 = x_2 - \lfloor\frac{a}{b}\rfloor y_2\),
计算 \(bx_2 + a\%b y_2 = \gcd(b,\ a\%b)\), 并不断递归, 得到答案
递归边界: \(\gcd(a,\ b) = 1\), 则 \(x = 1,\ y = 0\).
怎么写?
void ExGCD(int a, int b, int &x, int &y){
if(!b){
x = 1, y = 0;
return;
}
ExGCD(b, a%b, y, x);
y -= a/b * x;
}