前天讲了一堆的数论,还没什么时间整理,拓欧我也只是第一次接触(果然还是太蒟),搞了半个晚上才弄懂。避免遗忘或弄丢,写篇博文。
了解一下:扩展欧几里得算法,简称 exgcd,一般用来求解不定方程,求解线性同余方程,求解模的逆元等
引理:存在 x , y 使得 gcd(a,b)=ax+by,求 x,y
证明:
part 1:
(1)由gcd(a,b)= gcd(b,a mod b) //辗转相除法
得ax+by = by+(a mod b)*y
(2)bx+(a mod b)*y = bx+(a - (a div b)*b)*y //(a - (a div b)*b)相当于a mod b,总数-最大倍数=余数
= bx+ay-(a div b)*b*y //乘法分配律
=ay + b*(x-a div b*y) //乘法结合律,提取公因数b
(3)exgcd(ax+by)= exgcd(ay+b*(x-a div b*y))
part 2:
终止:当 b=0 时,ax = gcd(a,b),x=1,y=0
exgcd 的返回值就是gcd(a,b)
part 3:
那么怎么求其他解:
任取一组解(x2,y2),则ax1 + by1 = ax2 + by2(都等于gcd(a,b) = d),
变形得a(x1-x2)= b(y2-y1)
两边同时除以gcd(a,b)(a=a div d ,b=b div d)
此时a与b互素,因此(x1-x2)一定是b的整数倍,则y2-y1=ka,k为正整数
有了这个结论,很容易求出ax+by=-c
part 4:
ax+by=c 无整数解的情况:c不能被gcd(a,b)整除。(即c不是gcd(a,b)的倍数)
理由:因为 ax 与 by 均是gcd(a,b)的倍数,所以其和 ax+by 也是gcd(a,b)的倍数
因为 gcd(a,b) | ax , gcd(a,b) | by
所以 gcd(a,b) | ax+by
ll exgcd(ll a,ll b,ll x,ll y)
{
if (b==0)
{
x = 1;
y = 0;
return a;
}//终止
ll d = exgcd(b,a mod b,x,y);
ll t = x;//先存好现在的x
x = y;
y = t-(a div b)*y;
return d;
}
输入方正整数a,b,n,解方程ax≡b(mod n),也就是求解ax和b关于n同余
由同余定理,ax≡b(mod n)的充要条件是ax-b是n的整数倍
那么我们设这个倍数为y ,则得到 ax-ny=b,可以用上述算法解
当a和n互素的时候,此方程有为一解