1. 程式人生 > 其它 >[AcWing 878] 線性同餘方程

[AcWing 878] 線性同餘方程

複雜度 $ O(log(n)) $

總體複雜度 $ 10^{5} \times log(2 \times 10^{9}) \approx 4 \times 10^{6} $


點選檢視程式碼
#include<iostream>

using namespace std;
typedef long long LL;

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()
{
    int n;
    scanf("%d", &n);
    while (n --) {
        int a, b, m;
        scanf("%d %d %d", &a, &b, &m);
        int x, y;
        int d= exgcd(a, m, x, y);
        if (b % d)     puts("impossible");
        else    printf("%d\n", (LL)x * (b / d) % m);
    }
    return 0;
}

  1. 轉化為擴充套件歐幾里得演算法
    $ a \times x \equiv b \ (\bmod m) $ ,可以寫成 $ a \times x = m \times y + b $ ,移項 $ a \times x - m \times y = b $ ,可以把負號寫到 $ y $ 中,即 $ a \times x + m \times y = b $ ,由裴蜀定理可知當 $ b $ 是 $ a $ 和 $ m $ 最大公約數 $ gcd(a, m) $ 的倍數時,方程有解,至此,成功把線性同餘方程轉換成為擴充套件歐幾里得問題
    ① 若 $ b $ 不是 $ a $ 和 $ m $ 最大公約數 $ gcd(a, m) $ 的倍數,說明方程無解
    ② 若 $ b $ 是 $ a $ 和 $ m $ 最大公約數 $ gcd(a, m) $ 的倍數,則問題等價於求出一組 $ x' $ 和 $ y' $ ,使得 $ a \times x' + m \times y' = gcd(a, m) $ ,最後把方程兩邊同時乘以 $ \frac{b}{gcd(a, m)} $ 就是 $ a \times x + m \times y = d $ ,即 $ x = x' \times \frac{b}{gcd(a, m)} $ ,最後再 $ \bmod m $