acwing 878. 線性同餘方程
阿新 • • 發佈:2022-02-27
目錄
題目描述
給定 nn 組資料 ai,bi,mi,對於每組數求出一個 xi,使其滿足 \(ai×xi≡bi(\%mi)\),如果無解則輸出
impossible
。輸入格式
第一行包含整數 n。
接下來 n 行,每行包含一組資料 ai,bi,mi
輸出格式
輸出共 n 行,每組資料輸出一個整數表示一個滿足條件的 xi,如果無解則輸出
impossible
。每組資料結果佔一行,結果可能不唯一,輸出任意一個滿足條件的結果均可。
輸出答案必須在 int範圍之內。
資料範圍
1≤n≤105
1≤ai,bi,mi≤2×1091輸入樣例:
2 2 3 6 4 3 5
輸出樣例:
impossible -3
擴充套件歐幾里得演算法求解
分析
因為 $a∗x≡b(% m) $等價於 \(a∗x−b\) 是m的倍數,因此線性同餘方程等價為 \(a∗x+m∗y=b\)
根據 Bezout 定理,上述等式有解當且僅當 \(gcd(a,m)|b\) (\(b整除 gcd(a,m)\))
因此先用擴充套件歐幾里得演算法求出一組整數 \(x0,y0\) 使得 \(a∗x0+m∗y0=gcd(a,m)\)。 然後$ x=x0∗b/gcd(a,m)%m$ 即是所求。
https://www.acwing.com/solution/content/5937/
程式碼
#include<iostream> #include<algorithm> #include<cstdio> using namespace std; typedef long long LL; // 返回 gcd(a,b) 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) // b不能整除gcd(a,b),此時無解 { printf("impossible\n"); } else { LL res = (LL) x * b / d % m; printf("%lld\n", res); } } return 0; }