数论初步-GCD与ExGCD
最大公约数
a,b的最大公约数记做\(gcd(a,b)\)
辗转相除法
先上结论
\(gcd(a,b) = gcd(b,a\%b)\)
为什么呢?我们来尝试证明
首先,有规定:
\(gcd(a,0) =0\)
而且对于取模,有一个很好的方法改写:
\(a \% b=a-\lfloor\frac{a}{b}\rfloor*b\)
其实这个公式很好理解,\(\lfloor\frac{a}{b}\rfloor\)取出的是\(a\)中有几个完整的\(b\),\(\lfloor\frac{a}{b}\rfloor*b\)就是\(a\)包含\(b\)的最大整数倍
什么意思呢,比如带入4和11
\(\lfloor\frac{11}{4}\rfloor*4=8\)
看出来了吗?它提取出了11中完整的2个4,乘起来等于8再用\(a\)减去它就是\(\%b\)的余数了
接下来我们正式开始证明
不妨设\(g=gcd(a,b)\),则有\(a=a'g,b=b'g\),而且显然,\(gcd(a',b')=1\),即\(a'\)与\(b'\)互质
\(a\%b=
a-\lfloor \frac{a}{b} \rfloor=
a'g-\lfloor \frac{a'g}{b'g} \rfloor *b'g=
g(a'-\lfloor \frac{a'}{b'} \rfloor *b')=
g*a'\%b'\)
\(gcd(b,a\%b)=
gcd(b'g,g*a'\%b')=
g*gcd(b',a' \% b')=
gcd(a,b)*gcd(b',a' \% b')\)
于是我们只需要证明如果\(gcd(a',b')=1\),则\(gcd(b',a'\%b')=1\)
考虑反证法,设\(gcd(b',a'\%b')=q\neq 1\)
对于\(a'\),则显然有\(a'=kb'+r (k,r\in Z)\)
所以易得\(a'\%b'=r\),即\(gcd(b',r)=gcd(b',a'\%b')=q\)
所以\(b'=b''q,r=r'q\)
带入\(b',r\)得\(a'=kb'+r=k*b''q+r'q=q(kb''+r')\)
这样\(gcd(a',b')=gcd(q(kb''+r'),b''q)=q*gcd(kb''+r,b'')\)
又因为\(q\neq 1\),所以\(gcd(a',b')>1\)
这与\(gcd(a',b')=1\)矛盾,所以得出结论\(gcd(b',n\%b')=1\)
至此,我们正式证明出了\(gcd(a,b)=gcd(b,a\%b)\)
int gcd(int a,int b){
return b?gcd(b,a%b):a;
}
拓展欧几里得
考虑这样的方程
\(ax+by=gcd(a,b)\)
如何求出它的一组整数解?
套用一下辗转相除法求gcd的思想
假设我们已经知道了\(bx'+a\%b*y'=gcd(b,a\%b)\)
改写等式左侧
\(=bx'+(a-\lfloor \frac {a}{b} \rfloor *b)*y'\)
\(=bx'+ay'-\lfloor \frac {a}{b} \rfloor *b*y'\)
\(=ay'+b(x'-\lfloor \frac {a}{b} \rfloor *y')=gcd(b,a\%b)=gcd(a,b)\)
所以方程\(ax+by=gcd(a,b)\)的解\(\{x=y',y=x'-\lfloor \frac {a}{b} \rfloor *y'\}\)
得益于C++灵活的语法,我们可以简洁地用代码实现拓展欧几里得算法
void exgcd(int a,int b,int &x,int &y){
if(b==0){
x=1,y=0;
}else{
exgcd(b,a%b,y,x),y-=a/b*x;//注意这里传的是y,x
}
}
int x,y;
//例如方程114514x+1919810y=gcd(114514,1919810)
exgcd(114514,1919810,x,y)
如果是\(ax+bx=c\)呢?
事实上,只有当\(c\)是\(gcd(a,b)\)的倍数的时候原方程有解
因此设\(c=k*gcd(a,b)\)
\(ax*k+by*k=gcd(a,b)*k=c\)
所以我们只需要将原来的解乘上\(k\)就可以了
那么如果要多组解或者求x的最小整数解呢?
如果记两个数的最小公倍数为\(lcm(a,b)\),那么会有:
\(gcd(a,b)*lcm(a,b)=a*b\)
即\(lcm(a,b)=\frac{a*b}{gcd(a,b)}\)
记\(g=gcd(a,b)\)
则\(lcm(a,b)=\frac{a*b}{g}\)
考虑对方程左侧加上\(lcm(a,b)-lcm(a,b)\)
\(ax+lcm(a,b)+by-lcm(a,b)=c\)
\(ax+\frac{a*b}{g}+by-\frac{a*b}{g}=c\)
提取公因数
\(a(x+\frac{b}{g})+b(y-\frac{a}{g})=c\)
所以如若求最小正整\(x\),我们可以对其加减\(\frac{b}{g}\),而y其实可以由合法的x直接计算出来
总结:
若已有方程\(ax+by=c\)的一组解\(\{ x,y \}\),我们设\(g=gcd(a,b),t=\frac{b}{g}\)
则\(\{x+kt,c-\frac{ax}{b}\}(k \in Z)\)都是原方程的解
特别地,因为拓欧计算的\(x\)有可能为负数,所以最小正整\(x\)等于\((x\%t+t)\%t\)

浙公网安备 33010602011771号