浅谈扩展gcd
前言
有一段时间觉得扩展gcd很简单,然后不知道为什么有一段时间又觉得迷惑不清,于是现在我来重新梳理一下。
扩展gcd是什么
ax+by=gcd(a,b)ax+by=gcd(a,b)ax+by=gcd(a,b),a,ba,ba,b不完全为0,且x,yx,yx,y都为整数解。求解。
扩展gcdgcdgcd即用来求这个
注:[][][]为向下取整的意思
求解
假设a>ba>ba>b,
1.显然当b=0时,gcd(a,b)=a1.显然当b=0时,gcd(a,b)=a1.显然当b=0时,gcd(a,b)=a。此时,x=1.y=0x=1.y=0x=1.y=0
2.a<>ba<>ba<>b
设ax1+by1=gcd(a,b)ax1+by1=gcd(a,b)ax1+by1=gcd(a,b)
设bx2+(amodb)y2=gcd(b,amodb)bx2+(a mod b)y2=gcd(b,a mod b)bx2+(amodb)y2=gcd(b,amodb)
由gcd(a,b)=gcd(b,amodb)gcd(a,b) = gcd(b,a mod b)gcd(a,b)=gcd(b,amodb)
可知
ax1+by1=bx2+(amodb)y2ax1+by1=bx2+(a mod b)y2ax1+by1=bx2+(amodb)y2
可知
ax1+by1=bx2+(a−[a/b]∗b)y2=ay2+bx2−[a/b]∗by2ax1+ by1= bx2+ (a - [a / b] * b)y2=ay2+ bx2- [a / b] * by2ax1+by1=bx2+(a−[a/b]∗b)y2=ay2+bx2−[a/b]∗by2
得
ax1+by1==ay2+b(x2−[a/b]∗y2)ax1+ by1 == ay2+ b(x2- [a / b] *y2)ax1+by1==ay2+b(x2−[a/b]∗y2)
易得
x1=y2;y1=x2−[a/b]∗y2x1=y2; y1=x2- [a / b] *y2x1=y2;y1=x2−[a/b]∗y2
则可递归求出一组x,yx,yx,y,其他解见求解不定方程
模板
void exGcd(int a,int b,int &x,int &y)
{
if(b==0)
{
x=1;y=0;
return;
}
exGcd(b,a%b,x,y);
int t=x;x=y;y=t-a/b*y;
}
我们需要的解则就是x,yx,yx,y(该组解没有什么其他特点)
应用
……整理到现在我发现扩展gcd好simpl*啊
求乘法逆元
存在同余方程ax≡b(modn)ax≡b (mod n)ax≡b(modn)
如果gcd(a,n)==1gcd(a,n)==1gcd(a,n)==1且b==1b==1b==1时
ax≡1(modn)ax≡1 (mod n )ax≡1(modn)
可等同于求方程
ax+ny=1ax+ny=1ax+ny=1
过程:
设,x≡y(modp)x≡y(mod p)x≡y(modp)
可得:x+kp=yx+kp=yx+kp=y,kkk可正可负
相当于说,ppp是x的除以的数,yyy是余数,所以可得
那么把上面的方程代入亦可得解
则用扩欧求之
线性同余方程(其实和上面差不多)
ax≡b(modn)ax≡b (mod n)ax≡b(modn)
当bbb%(gcd(a,n)==0)(gcd(a,n)==0)(gcd(a,n)==0),则有解
可转换为ax+ny=bax+ny=bax+ny=b
则用扩欧求之
求解不定方程
ax+by=cax+by=cax+by=c
首先你必须要保证gcd(a,b)gcd(a,b)gcd(a,b)要整除c,
设g=gcd(a,b),a′=a/g,b′=b/g,c′=c/gg=gcd(a,b),a'=a/g,b'=b/g,c'=c/gg=gcd(a,b),a′=a/g,b′=b/g,c′=c/g
由线性同余方程,我们可以得出a′x′+b′y′=1a'x'+b'y'=1a′x′+b′y′=1的整数解(看上面mo)
那么a′c′x′+b′c′y′=c′a'c'x'+b'c'y'=c'a′c′x′+b′c′y′=c′
然后可得 a′gc′x′+b′gc′y′=c′ga'gc'x'+b'gc'y'=c'ga′gc′x′+b′gc′y′=c′g
即ac′x′+bc′y′=cac'x'+bc'y'=cac′x′+bc′y′=c
所以x0=c′x′x0=c'x'x0=c′x′ , y0=c′y′y0=c'y'y0=c′y′则为方程的一组解
然后
因为a′x+b′y=ca'x+b'y=ca′x+b′y=c和a′x≡c′(modb′)a'x≡c'(modb')a′x≡c′(modb′)可以互相转换(线性同余方程的应用)
所以xxx是模b′b'b′同余的一个剩余类
可得
x=x0+b′∗t,y=y0−a′∗t,t是整数x=x0+b'*t,y=y0-a'*t,t是整数x=x0+b′∗t,y=y0−a′∗t,t是整数
剩余类:一个整数被正整数n除后,余数有n种情形:0,1,2,3,…,n-1,它们彼此对模n不同余。这表明,每个整数恰与这n个整数中某一个对模n同余。这样一来,按模n是否同余对整数集进行分类,可以将整数集分成n个两两不相交的子集。我们把(所有)对模n同余的整数构成的一个集合叫做模n的一个剩余类。
加油搞懂它!!!