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