裴蜀定理、扩展欧几里得算法与线性同余方程

裴蜀定理:

对于任意正整数 a , b , a,b, a,b,一定存在非零整数 x , y x,y x,y使得
a x + b y = gcd ⁡ ( a , b ) ax+by=\gcd(a,b) ax+by=gcd(a,b)
x , y x,y x,y可用扩展欧几里得算法求出。

扩展欧几里得:

由欧几里得算法得
gcd ⁡ ( a , b ) = gcd ⁡ ( b , a % b ) \gcd(a,b)=\gcd(b,a\%b) gcd(a,b)=gcd(b,a%b)
由裴蜀定理
a x + b y = gcd ⁡ ( a , b ) ax+by=\gcd(a,b) ax+by=gcd(a,b)
b = 0 b=0 b=0时, gcd ⁡ ( a , 0 ) = a \gcd(a,0)=a gcd(a,0)=a x = 1 , y = 0 x=1,y=0 x=1,y=0
右边
b x ′ + ( a % b ) y ′ = d bx'+(a\%b)y'=d bx+(a%b)y=d
因为
a % b = a − ⌊ a b ⌋ b a\%b=a-\left \lfloor \frac{a}{b} \right \rfloor b a%b=abab
所以右边为
b x ′ + ( a − ⌊ a b ⌋ b ) y ′ = d bx'+(a-\left \lfloor \frac{a}{b} \right \rfloor b)y'=d bx+(abab)y=d
整理得
a y ′ + b ( x ′ − ⌊ a b ⌋ y ′ ) = d ay'+b(x'-\left \lfloor \frac{a}{b} \right \rfloor y')=d ay+b(xbay)=d
就递归为了求 e x g c d ( b , a % b ) , b = 0 exgcd(b,a\%b),b=0 exgcd(b,a%b),b=0时可得出结果

#include<bits/stdc++.h>
using namespace std;
int t,a,b,x,y;
int exgcd(int a,int b,int &x,int &y){
    
    
    if(!b){
    
    
        x=1,y=0;
        return a;
    }
    int d=exgcd(b,a%b,y,x);
    y-=a/b*x;
    return d;
}
int main(){
    
    
    cin>>t;
    while(t--){
    
    
        cin>>a>>b;
        exgcd(a,b,x,y);
        cout<<x<<" "<<y<<endl;
    }
}

对于一般方程 a x + b y = c ax+by=c ax+by=c d = gcd ⁡ ( a , b ) d=\gcd(a,b) d=gcd(a,b),当且仅当 d ∣ c d\mid c dc时方程有解。

先用扩展欧几里得求出 a x 0 + b y 0 = gcd ⁡ ( a , b ) ax_0+by_0=\gcd(a,b) ax0+by0=gcd(a,b)的一组特解 x 0 , y 0 x_0,y_0 x0,y0

于是再求齐次解

a x + b y = 0 ax+by=0 ax+by=0

齐次解为
x = k ∗ b gcd ⁡ ( a , b ) , y = − k ∗ a gcd ⁡ ( a , b ) , ( k ∈ Z ) x=k*\frac{b}{\gcd(a,b)},y=-k*\frac{a}{\gcd(a,b)},(k\in Z) x=kgcd(a,b)b,y=kgcd(a,b)a,(kZ)
带入验证
a ∗ k ∗ b gcd ⁡ ( a , b ) + b ∗ ( − k ∗ a gcd ⁡ ( a , b ) ) = 0 成 立 , ( k ∈ Z ) a*k*\frac{b}{\gcd(a,b)}+b*(-k*\frac{a}{\gcd(a,b)})=0成立,(k\in Z) akgcd(a,b)b+b(kgcd(a,b)a)=0,(kZ)
所以通解 = = =齐次解 + + +特解
x = x 0 + k ∗ b gcd ⁡ ( a , b ) , y = y 0 − k ∗ a gcd ⁡ ( a , b ) , ( k ∈ Z ) x=x_0+k*\frac{b}{\gcd(a,b)},y=y_0-k*\frac{a}{\gcd(a,b)},(k\in Z) x=x0+kgcd(a,b)b,y=y0kgcd(a,b)a,(kZ)

线性同余方程:

给定 a , b , m , a,b,m, a,b,m,求出 x x x使其满足
a x ≡ b ( m o d    m ) ax\equiv b(\mod m) axb(modm)
等价于:
∃ y ∈ Z , 使 得 a x = m y + b \exist y \in Z,使得ax=my+b yZ,使ax=my+b
移项:
a x − m y = b ax-my=b axmy=b
有解的条件为 gcd ⁡ ( a , m ) ∣ b \gcd(a,m) \mid b gcd(a,m)b
特殊情况: b = 1 , a , m b=1,a,m b=1,a,m互质时就是求 a a a的逆元

y ′ = − y y'=-y y=y
我们可以求出 a x + m y ′ = gcd ⁡ ( a , m ) ax+my'=\gcd(a,m) ax+my=gcd(a,m)
所以等式两边只需同乘 b gcd ⁡ ( a , m ) \frac{b}{\gcd(a,m)} gcd(a,m)b
等式右边就是 b b b了,就可以求得原式了。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
int t,a,b,m,x,y;
int exgcd(int a,int b,int &x,int &y){
    
    
    if(!b){
    
    
        x=1,y=0;
        return a;
    }
    int d=exgcd(b,a%b,y,x);
    y-=a/b*x;
    return d;
}
int main(){
    
    
    cin>>t;
    while(t--){
    
    
        cin>>a>>b>>m;
        int d=exgcd(a,m,x,y);
        if(b%d!=0) puts("impossible");
        else cout<<(LL)b/d*x%m<<endl;
    }
}

猜你喜欢

转载自blog.csdn.net/messywind/article/details/113758822