扩展欧几里得
- 裴蜀定理
方程ax + by = c有解的充要条件是(a, b) 是 c 的因数,换种说法,即c为gcd(a, b)(a,b的最大公约数)的倍数
引入gcd(a, b)
int gcd (int a, int b) {
if (b == 0)
return a;
else
return gcd(b, a % b);
}
- 丢番图方程
不定方程(丢番图方程)是指未知数的个数多于方程个数,且未知数受到某些限制(即要求有理数、整数或正整数等)的方程式或方程组
- 逆元
引入求余概念
(a + b) % p = (a%p + b%p) % p (Y)
(a - b) % p = (a%p - b%p) % p (Y)
(a * b) % p = (a%p * b%p) % p (Y)
(a / b) % p = (a%p / b%p) % p (N)
除法是不成立的
a * x = 1
那么x是a的倒数,x = 1/a
如果a不是1,那x就是小数
在数论中, 很多时候都需要求余,所以问题变成
a * x = 1 (mod p) 此时x一定等于1/a吗,显然不是
此时,我们就把x看成a的倒数,但是加了一个求余条件,所以x叫做 a关于p的逆元
例如 2 * 3 % 5 = 1,那么3就是2关于5的逆元,也可以说2和3关于5互为逆元
(注意,只有a和p互质,a才有关于p的逆元)
来到我们的重头戏扩展欧几里得了
a * x + b * y = 1, 如果a和b互质,有解
这个解的x就是a关于b的逆元, y就是b关于a的逆元
为什么呢?
对公式两边同时求余b
a * x % b + b * y % b = 1 % b
a * x % b = 1 % b => a * x = 1 (mod b)
同理 同时求余a
b * y % a = 1 % a => b * y = 1 (mod a)
我们假设 a > b
1、当 b = 0 时,gcd(a, b) = a, 此时 x = 1, y = 0
2、当 a * b != 0 时
a * x1 + b * y1 = gcd(a, b)
让 a = b
有 b * x2 + (a mod b) y2 = gcd (b, a mod b)
我们由朴素欧几里得得出 gcd (a, b) = gcd (b, a mod b);
根据恒等
a * x1 + b * y1 = b * x2 + (a mod b) * y2
a mod b = a - (a/b)*b
代入上式得
a * x1 + b * y1 = b * x2 + a*y2 - (a/b)*b*y2
有 x1 = y2, y1 = x2 - (a/b)*y2
int ex_gcd (int a, int b, int &x, int &y) {
if (b == 0) {
x = 1;
y = 0;
return a;
}
int res = ex_gcd(b, a % b, x, y);
int t = x;
x = y;
y = t - (a/b)*y;
return res;
}