浅谈扩展gcd

浅谈扩展gcd

前言

有一段时间觉得扩展gcd很简单,然后不知道为什么有一段时间又觉得迷惑不清,于是现在我来重新梳理一下。

扩展gcd是什么

ax+by=gcd(a,b)ax+by=gcd(a,b)a,ba,b不完全为0,且x,yx,y都为整数解。求解。

注:[][]为向下取整的意思

求解

假设a>ba>b,
1.b=0gcd(a,b)=a1.显然当b=0时,gcd(a,b)=a。此时,x=1.y=0x=1.y=0
2.a<>ba<>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)
gcd(a,b)=gcd(b,amodb)gcd(a,b) = gcd(b,a mod b)
可知
ax1+by1=bx2+(amodb)y2ax1+by1=bx2+(a mod b)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] * by2

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] *y2
则可递归求出一组x,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,y(该组解没有什么其他特点)

应用

……整理到现在我发现扩展gcd好simpl*啊

求乘法逆元

存在同余方程axb(modn)ax≡b (mod n)
如果gcd(a,n)==1gcd(a,n)==1b==1b==1
ax1(modn)ax≡1 (mod n )
可等同于求方程
ax+ny=1ax+ny=1

过程:

设,xy(modp)x≡y(mod p)
可得:x+kp=yx+kp=y,kk可正可负
相当于说,pp是x的除以的数,yy是余数,所以可得
那么把上面的方程代入亦可得解

则用扩欧求之

线性同余方程(其实和上面差不多)

axb(modn)ax≡b (mod n)
bb%(gcd(a,n)==0)(gcd(a,n)==0),则有解
可转换为ax+ny=bax+ny=b
则用扩欧求之

求解不定方程

ax+by=cax+by=c
首先你必须要保证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/g
由线性同余方程,我们可以得出ax+by=1a'x'+b'y'=1的整数解(看上面mo)
那么acx+bcy=ca'c'x'+b'c'y'=c'
然后可得 agcx+bgcy=cga'gc'x'+b'gc'y'=c'g
acx+bcy=cac'x'+bc'y'=c
所以x0=cxx0=c'x'y0=cyy0=c'y'则为方程的一组解

然后
因为ax+by=ca'x+b'y=caxc(modb)a'x≡c'(modb')可以互相转换(线性同余方程的应用)
所以xx是模bb'同余的一个剩余类
可得
x=x0+bt,y=y0attx=x0+b'*t,y=y0-a'*t,t是整数

剩余类:一个整数被正整数n除后,余数有n种情形:0,1,2,3,…,n-1,它们彼此对模n不同余。这表明,每个整数恰与这n个整数中某一个对模n同余。这样一来,按模n是否同余对整数集进行分类,可以将整数集分成n个两两不相交的子集。我们把(所有)对模n同余的整数构成的一个集合叫做模n的一个剩余类。

加油搞懂它!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章