扩展欧几里得算法
扩展欧几里得算法(扩O)能在求gcd(a,b)的同时求出丢番图方程ax+by=gcd(a, b)的解。
然而怎么求呢?我们观察gcd(a, b)=gcd(b, a%b),所以设如下两个方程:
ax+by = gcd(a,b) = d;
bx’+(a%b)y’ = gcd(b,a%b);
明显gcd(a,b) = gcd(b,a%b),也就是ax+by = bx’+(a%b)y’。
为了求得x与y,我们需要保证a,b不变,所以:ax+by = bx’+(a%b)y’ = bx’+(a-[a/b]*b)y’
=ay’ + b(x’ – [a/b]y’) ([a/b]表示a/b的值向下取整。)
所以可得恒等关系: x = y’ , y = (x’ – [a/b]y’)。这样就求出了一组特解。
那么如何求全解呢?直接给出递推式:
x = x0 + (b/gcd)*t
y = y0 – (a/gcd)*t
明显,b/gcd与a/gcd是互素的,也就是说它们的gcd为1。如果它们再除以一个值,某些解可能就不是整数了。
裴蜀定理
扩O有什么卵用吗?其实它可以求线性丢番图方程(不定方程)。
对任何整数a、b和它们的最大公约数d,关于未知数x和y的线性丢番图方程(称为裴蜀等式):
ax + by = m
有解当且仅当m是d的倍数。因为ax+by=gcd(a,b)。如果m不是d的整数倍的话,m就不是整数了。而因为是丢番图方程,所以a,b,x,y都为整数。m不为整数时方程无解。
裴蜀等式有解时必然有无穷多个整数解,每组解x、y都称为裴蜀数,可用扩O求得。只要将x与y同时乘上m/gcd(a,b)就行了。
特别来说,方程 ax + by = 1 有解当且仅当整数a和b互素。(因为gcd(a,b)=1)
乘法逆元
给定一个形如ax≡1 (mod m)的关于x的方程,x即为a关于m的乘法逆元。
怎么求呢?我们把它等价一下:ax mode m = 1 mod m = 1,ax=m(-y)+1,ax+my=1。
也就是说,只要求出ax+my=1这个方程的解就行了。是不是有点熟悉?对,用扩O+裴蜀求出x,y。
(注意要满足gcd(a,m)=1)
但是明显,一道题目出给你不可能让你输出无数解,通解也不现实,一般是让你求出x最小的正整数解。那怎么办呢?
x的通解是x0+m/gcd*t,在乘法逆元情况下gcd=1,所以不用考虑。所以x的通解是x0+mt。
因为通解是x0+mt,明显最小正整数解的区间是[ 0,m),所以似乎只要让x0%m就可以找到最小解了。
可是万一x0%m是负数呢?答案是取绝对值就好了。(我也不知道为什么)
下面贴代码:(待更)