拓展欧几里得方法解决的标准问题是
a x + b y = g c d ( a , b ) ax+by=gcd(a,b) ax+by=gcd(a,b)
由于有2个未知数,却只有1个方程,所以方程的解并不唯一。通过欧几里得算法,我们得到了该方程的一对特解 x 0 x_0 x0和 y 0 y_0 y0 ,由齐次方程 a x + b y = 0 ax+by=0 ax+by=0可以得齐次通解
{ x = b g c d ( a , b ) y = − a g c d ( a , b ) \left\{ \begin{array}{lr} x= \dfrac{b}{gcd(a,b)} \\\\ y=-\dfrac{a}{gcd(a,b)}\\ \end{array} \right. ⎩⎪⎪⎪⎨⎪⎪⎪⎧x=gcd(a,b)by=−gcd(a,b)a
由此我们可以得到原方程的通解
{ x = x 0 + t b g c d ( a , b ) y = y 0 − t a g c d ( a , b ) , t ∈ N + \left\{ \begin{array}{lr} x= x_0+t\dfrac{b}{gcd(a,b)} \\\\ y=y_0-t\dfrac{a}{gcd(a,b)}\\ \end{array} ,t \ \in \ N^+ \right. ⎩⎪⎪⎪⎨⎪⎪⎪⎧x=x0+tgcd(a,b)by=y0−tgcd(a,b)a,t ∈ N+
当我们需要求一般情况
a x + b y = c ax+by=c ax+by=c
可以在标准问题的基础上进行求解,显然仅当 g c d ( a , b ) ∣ d gcd(a,b)\ | \ d gcd(a,b) ∣ d,即 c % g c d ( a , b ) = 0 c\ \%\ gcd(a,b)=0 c % gcd(a,b)=0时,新方程才有整数解,新的特解为标准特解的 k = c g c d ( a , b ) k=\dfrac{c}{gcd(a,b)} k=gcd(a,b)c倍,即
{ X 0 = k x 0 Y 0 = k y 0 \left\{ \begin{array}{lr} X_0= kx_0 \\\\ Y_0= ky_0\\ \end{array} \right. ⎩⎨⎧X0=kx0Y0=ky0
typedef long long LL;
void ex_gcd(LL a,LL b,LL & x,LL & y,LL & d)
{
if(!b) d=a,x=1,y=0;
else
ex_gcd(b,a%b,y,x,d),y-=x*(a/b);
}
LL gcd(LL a,LL b)
{
return !b?a:gcd(b,a%b);
}
注:ex_gcd()产生的d就是gcd(),因为算法是完全一致的。
定理1 :对于二元一次方程 a ∗ x + b ∗ y = c a*x+b*y=c a∗x+b∗y=c ,其等价为 a ∗ x ≡ c ( m o d b ) a*x\equiv c(mod \:\,b) a∗x≡c(modb),该方程有整数解的充分条件是 c m o d g c d ( a , b ) = 0 c \: \, mod \: \, gcd(a,b)=0 cmodgcd(a,b)=0,若方程有整数解,则共有 g c d ( a , b ) gcd(a, b) gcd(a,b)个解。
定理2:若 $x_0 、 、 、y_0 $ 为 a ∗ x + b ∗ y = c a*x+b*y=c a∗x+b∗y=c 的一组解,则该方程的任一解可表示为: { x = x 0 + b ∗ t / G C D ( a , b ) y = y 0 − a ∗ t / G C D ( a , b ) , t ∈ Z \left\{\begin{matrix}x=x_0+b*t/GCD(a,b) \\ y=y_0-a*t/GCD(a,b) \end{matrix}\right.,t\in Z {x=x0+b∗t/GCD(a,b)y=y0−a∗t/GCD(a,b),t∈Z
定理3: 若 g c d ( a , b ) = d gcd(a,b)=d gcd(a,b)=d,则方程 $ a*x \equiv c (mod :,b)$ 在 [ 0 , b / d − 1 ] [0, b/d - 1] [0,b/d−1] 上有唯一解。
通过定理2来拓展方程的解,来调整x的范围,将 a ∗ x 0 + b ∗ y 0 = c a*x_0+b*y_0=c a∗x0+b∗y0=c拓展为 a ∗ ( x 0 + t ∗ k ) + b ∗ ( y 0 − t ∗ k ) = c , k ∈ Z a*(x_0+t*k)+b*(y_0-t*k)=c,k \in Z a∗(x0+t∗k)+b∗(y0−t∗k)=c,k∈Z,从而使得所得到的 x 尽可能的小,通过式子 x = ( x m o d t + t ) m o d t x=(x\:\ mod\:\, t+t)\:\,mod\:\,t x=(x modt+t)modt 来约束结果一定是一个正数借助定理3,我们可以取出最小正整数解 a n s = ( x % r + r ) % r ans=(x \ \% \ r + r)\ \%\ r ans=(x % r+r) % r,其中 r = b g c d ( a , b ) r=\dfrac{b}{gcd(a,b)} r=gcd(a,b)b
方程
a ∗ x ≡ b ( m o d n ) a*x\equiv b(mod \:\,n) a∗x≡b(modn)
等价于
a x + n y = b ax+ny=b ax+ny=b
有整数解条件
g c d ( a , n ) ∣ b < = = > b % g c d ( a , n ) = 0 gcd(a,n) \ | \ b \ <==>\ b \ \% \ gcd(a,n)=0 gcd(a,n) ∣ b <==> b % gcd(a,n)=0
整数解的数量为
g c d ( a , n ) gcd(a,n) gcd(a,n)
特解为
X 0 = x 0 ∗ b g c d ( a , n ) , w h e r e x 0 f i t s a x 0 + n y 0 = g c d ( a , n ) X_0=x_0*\dfrac{b}{gcd(a,n)}, \ where \ x_0 \ fits \ \ \ ax_0+ny_0=gcd(a,n) X0=x0∗gcd(a,n)b, where x0 fits ax0+ny0=gcd(a,n)
通解为
X = ( X 0 + k n g c d ( a , n ) ) % n , k ∈ Z + X=(X_0+k\dfrac{n}{gcd(a,n)})\ \% \ n ,k\in Z^+ X=(X0+kgcd(a,n)n) % n,k∈Z+
最小正整数解为
X m i n = ( X 0 % r + r ) % r , r = n g c d ( a , n ) X_{min}=(X_0\ \% \ r + r)\ \% \ r,\ r=\dfrac{n}{gcd(a,n)} Xmin=(X0 % r+r) % r, r=gcd(a,n)n
void RemainderEquation(int a,int b,int n)
{
int X,Y,d,r;
long long res;
long long min_res;
d=gcd(a,n);
ex_gcd(a,n,X,Y);
if(b%d == 0)
{
r=n/d;
X = X * (b / d) % n;//特解
for(int i = 0 ; i < d; i++)
{
res = (X + (i * r)) % n;//通解
printf("%lld\n",res); //输出所有解
}
min_res=(X%(n/d)+(n/d))%(n/d);
cout<<min_res<<endl; //输出最小解
}else
{
printf("No Sulutions!\n");
}
}
https://blog.csdn.net/u011815404/article/details/81302830 (主要)
https://www.cnblogs.com/linyujun/p/5167916.html (次要)