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

扩展欧几里得

设最大公约数为 d,

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

递归过程中,

(ecause) (by : + :(a : - : lfloor frac{a}{b} floor : cdot : b) : x : = : d)

( herefore) (ax : + (y : - : lfloor frac{a}{b} floor : cdot : x) : b : = : d)

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

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

const char nl = '
';

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 = '
';

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;
}

原文地址:https://www.cnblogs.com/xiaoran991/p/14401417.html