扩展欧几里得(应用:线性同余方程)

扩展欧几里得

设最大公约数为 d,

裴蜀定理:对于任意正整数 a, b,一定存在非零整数 x, y,使得 \(ax \: + \: by \: = \: d\)

递归过程中,

\(\because\) \(by \: + \:(a \: - \: \lfloor \frac{a}{b} \rfloor \: \cdot \: b) \: x \: = \: d\)

\(\therefore\) \(ax \: + (y \: - \: \lfloor \frac{a}{b} \rfloor \: \cdot \: x) \: b \: = \: d\)

时间复杂度:O(\(\log\)n)

#include <bits/stdc++.h>
using namespace std;

const char nl = '\n';

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(){
    ios::sync_with_stdio(false);
//    cin.tie(nullptr);

    int a, b;
    while (cin >> a >> b){
        int x = 0, y = 0;
        exgcd(a, b, x, y);
        cout << x << " " << y << nl;
    }
    return 0;
}

线性同余方程

时间复杂度:O(\(\log\)n)

https://www.luogu.com.cn/problem/P1082

题意:求关于 x 的同余方程 \(a x \equiv 1 \pmod {b}\) 的最小正整数解。

#include <bits/stdc++.h>
using namespace std;

const char nl = '\n';

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(){
    ios::sync_with_stdio(false);
//    cin.tie(nullptr);

    int a, b;
    while (cin >> a >> b){
        int x, y;
        exgcd(a, b, x, y);
        cout << (x + b) % b << nl;
    }
    return 0;
}

posted @ 2021-02-14 01:10  小燃、  阅读(48)  评论(0编辑  收藏  举报