扩展欧几里得

贝祖等式

给定两个整数 a,ba,b,必存在整数 x,yx,y 使得 ax+by=cax + by = cgcd(a,b)cgcd(a,b)|c

算法分析

因为

gcd(a,b)=gcd(b,a%b)gcd(a,b) = gcd(b,a\%b)

可得

bx+(aa/bb)y=gcd(b,a%b)bx^{'} + (a - \lfloor a / b \rfloor * b)y^{'} = gcd(b, a\%b)

继而

ay+b(xa/by)=gcd(b,a%b)=gcd(a,b)ay^{'} + b(x^{'} - \lfloor a / b \rfloor * y^{'}) = gcd(b,a\%b) = gcd(a,b)

故而

x=y,y=xa/byx = y^{'},y = x^{'} - \lfloor a / b \rfloor * y^{'}
#include<iostream>
#include<algorithm>
using namespace std;

void exgcd(int a, int b, int &x, int &y){
    if (!b){
        x = 1, y = 0;
        return;
    }
    exgcd(b, a % b, y, x);
    y -= a / b * x;
    return;
}

int main(){
    int n; cin >> n;
    while (n -- ){
        int a, b, x, y; cin >> a >> b;
        exgcd(a, b, x, y);
        printf("%d %d\n", x, y);
    }
}

时间复杂度分析

  • 这题的时间复杂度和欧几里得算法一样。欧几里得算法时间复杂度 O(logb)O(\log b),总时间复杂度 O(nlogb)O(n \log b)

线性同余方程

给定 nn 组数据 ai,bi,mia_i,b_i,m_i,对于每组数求出一个 xix_i,使其满足 aixibi(modm)a_i*x_i\equiv b_i\pmod m,如果无解则输出 impossible

aixibi(modm)a_i*x_i\equiv b_i\pmod m

可得 yZ\exists y \in Z

ax=my+bax+my=bax = my + b \Rightarrow ax + my^{'} = b

由之前的贝祖等式可知,只要 gcd(a,m)bgcd(a,m)|b,我们就可以利用扩展欧几里得算法求解线性同余方程。

#include<iostream>
#include<algorithm>

using namespace std;
void exgcd(int a, int b, int &x, int &y){
    if (!b){
        x = 1, y = 0;
        return;
    }
    exgcd(b, a % b, y, x);
    y -= a / b * x;
}


int main(){
    int n; cin >> n;
    while (n -- ){
        int a, b, m; cin >> a >> b >> m;
        int x, y;
        exgcd(a, m, x, y);
        int gcd = a * x + m * y;
        if (b % gcd == 0)
            cout << (long long)b / gcd * x % m << endl; 
        else 
            cout << "impossible" << endl;
    }
}

最后更新于