数论-线性同余方程的解法

一 拓展欧几里得方法

1. 标准方程

拓展欧几里得方法解决的标准问题是

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=y0tgcd(a,b)a,t  N+

2. 一般情况

当我们需要求一般情况
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

3. 欧几里得算法的代码模板(标准方程)

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. 相关性质定理

定理1 :对于二元一次方程 a ∗ x + b ∗ y = c a*x+b*y=c ax+by=c ,其等价为 a ∗ x ≡ c ( m o d    b ) a*x\equiv c(mod \:\,b) axc(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 ax+by=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+bt/GCD(a,b)y=y0at/GCD(a,b),tZ

定理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/d1] 上有唯一解。

2. 最小正整数解

通过定理2来拓展方程的解,来调整x的范围,将 a ∗ x 0 + b ∗ y 0 = c a*x_0+b*y_0=c ax0+by0=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+tk)+b(y0tk)=c,kZ,从而使得所得到的 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

3. 线性同余方程的解

方程
a ∗ x ≡ b ( m o d    n ) a*x\equiv b(mod \:\,n) axb(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=x0gcd(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,kZ+

最小正整数解为

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

4.代码模板 a ∗ x ≡ b ( m o d    n ) a*x\equiv b(mod \:\,n) axb(modn)

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 (次要)

你可能感兴趣的:(算法学习)