欧几里得算法:
求a,b的最大公约数
gcd(a,b)= gcd(b,a%b)
ll gcd(ll a,ll b) { return b==0?a:gcd(b,a%b); }
扩展欧几里得算法:
如果a,b是整数,一定存在x和y使得ax+by=gcd(a,b)
也就是ax+by=m的话,m一定是gcd(a,b)的倍数
假设当前我们在求的时a和b的最大公约数,而我们已经求出了下一个状态:b和a%b的最大公因数,并且求出了一组x1和y1使得 : b * x1+(a%b) * y1 = gcd
结论: x = y1 , y = x1 – a / b * y1
得到的是特解,如何由特解推出其他的整数解:
对于关于x,y的方程a * x + b * y = g 来说,让x增加b/g,让y减少a/g,等式两边还相等。
对于ax+by=c的一组解(x0,y0),则它的任意整数解都可以写成(x0+k * b1,y0+k * a1)其中 b1 = b / gcd(a,b), a1 = a/gcd(a,b).
我们就可以用 (x0 % b1 + b1 ) % b1得到它的最小正整数解了
此处x0= x * c / gcd(a,b)
#include<iostream> #include<cstdio> #include<cmath> using namespace std; int exgcd(int a,int b,int &x,int &y)//扩展欧几里得算法 { if(b==0) { x=1; y=0; return a; //到达递归边界开始向上一层返回 } int gcd=exgcd(b,a%b,x,y); int y1=y; //把x y变成上一层的 int x1=x; y=x1-(a/b)*y1; x=y1; return gcd; //得到a b的最大公因数 }