1.扩展欧几里得算法
扩展欧几里得算法用来解决这样一个问题:
给定两个非零整数a,b,求一组整数解(x,y),使得ax+by=gcd(a,b)成立
对于gcd,考虑使用欧几里得算法,也就是辗转相除法,临界条件是当b=0,此时a的值就是gcd的值,即此时a*1+b*0=gcd(a,b)成立
int gcd(int a,int b)
{
return !b?a:gcd(b,a%b);
}
假设当计算gcd(a,b)时,有ax1+by1=gcd成立;而在下一步计算gcd(b,a%b)时,又有bx2+(a%b)y2=gcd。因此ax1+by2=bx2+(a%b)y2成立。考虑到a%b=a-(a/b)*b,那么ax1+by1=bx2+(a-(a/b)*b)y2成立,整理可得ax1+by1=ay2+b(x2-(a/b)y2),可解出结果为,
由以上分析,我们可以通过反推来获得x1,y1,于是我们只需得到边界情况即可利用递归得到最初情况下要求的x,y;
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; //g是gcd
}
这样,我们就得到的第一组解,同时可以通过下面式子得到通解:
证明如下:
假设新的解为x+s1,y-s2,即有a*(x+s1)+b(y-s2)=gcd,联立ax+by=gcd得as1=bs2,于是,为了让s1和s2尽可能小,可以通过除一个尽可能大得数同时保证它们仍是整数。显示,gcd符合,于是,也就是说s1和s2得最小取值整数时b/gcd 和a/gcd。
也就是说,x和y的所有解,分别以b/gcd 和 a/gcd 为周期。
在考虑解的最小非负整数,只对x'分析,由于计算出来的x可能是负数,所有x'的最小非负整数为
(x%+)%
2.方程ax+by=c求解
利用1的算法,我们可以求解ax+by=c,c为任意整数。
首先ax+by=gcd,假设由exGcd()得到的解为(x0,y0)。两边同时乘以c/gcd,即得到,那么是ax+by=c的一组解。
同时注意因为我们求得是整数解,所以这样做成立得充要条件是c%gcd==0。
同样根据1得通解求法,我们发现最后还是有,最后的通解为
同样考虑最小非负整数解,只对x'分析
(%+)%
3.同余式ax=c(mod m)的求解
同余式,对于整数a,b,m来说,如果(a-b)%m=0,那么就说a与b模m同余,对应的同余式为a=b(mod m)。
根据同余式的定义,有(ax-c)%m=0成立。因此存在整数y使得ax-c=my,移项并令y=-y,得ax+my=c .
这样也就变换为 2得问题。
考虑到对同余式来说,虽然x有很多解,但很多解在模m的情况下意义是相同的。
于是对于,当K=0,1,2......gcd(a,m)-1时,所得到的解在模m下的意义是不同的,而其他解都可以在这里取到对应的值。
证明如下:
x'%m,只需考虑这一部分模m的影响。变换形式,可以看到如果K>=gcd(a,m),那么分数可以转换位一个整数+一个小于0的分数,其中整数部分*m对m取余是没有意义的。
4.逆元的求解
逆元(此处特指乘法逆元),假设a,b,m是整数,m>1,具有ab=1(mod m)成立,那么就说a和b互为模m的逆元,一般也记为a=1/b(mod m)或 b=1/a(mod m)。
通俗的说,如果两个数的乘积模m后等于1,那么ab互为m的逆元。(逆元的定义是同余式的一个特殊情况,即c=1).
逆元的作用
对于除法,(b/a)%m=((b%m)/(a%m))%m是不成立的,当b非常大时,直接计算是不实用的。
我们可以利用逆元,消除被除数a也就消除了除法。所以 找到a模m的逆元x,就有 (b/a)%m=(b*x)%m成立。
由定义可知,求x也就是解同余式ax=1(mod m),并且在实际应用中选x的最小正整数解作为所求x.
根据3,也就是求ax+my=1,这里我们注意到因为1%gcd(a,m)=0,所以gcd(a,m)=1,所以我们只需求的x得一个解后,利用公式直接得逆元.
int inverse(int a,int m)
{
int x,y;
int g=exGcd(a,m,x,y);
return (x%m+m)%m;
}
如果m是素数,且a不是m的倍数,可以直接使用费马小定理来得到逆元。
费马小定理:设m是素数,a是任意整数且a不是m的倍数,则.
所以a模m的逆元是%m
如果gcd(a,m)!=1,那么就不能用逆元的方法。
假设(b/a)%m=x,因此存在整数k,使得b/a=km+x,即b=kma+ax,于是有b%(ma)=ax,于是有(b%(ma))/a=x=(b/a)%m。
所以可以使用该公式求,可能的问题是am可能溢出。