Gehe zu: Mein eigener Blog
Thema
Luogu P1082 Kongruenzgleichung
Antworten
Definieren Sie gcd (a, b) als den größten gemeinsamen Teiler von a, b.
Nach dem Satz von Euklid:
Insbesondere gilt: gcd (a, 0) = a
Aus dem Satz von Pei Shu:
Erweiterter euklidischer Algorithmus: Angenommen, a * x + b * y = gcd (a, b)
1. Wenn b = 0, gcd (a, b) = a ist, ist die Lösung x = 1, y = 0
2.b! = 0, nehme an
Es kann äquivalent umgewandelt werden in:
Verglichen mit der Gleichung a * x + b * y = gcd (a, b) erhalten wir: x = y ', y = x' - (a / b) * y ', wiederholen die Operation, ändern rekursiv x, y, um zu finden Holen Sie sich eine Reihe von speziellen Lösungen x0, y0.
Erweiterung (kein Beweis in diesem Artikel): Sei d = gcd (a, b), für die allgemeinere Gleichung a * x + b * y = c gibt es genau dann eine Lösung, wenn d | c. Unter der Annahme, dass eine Menge spezieller Lösungen, die aus a * x + b * y = d erhalten werden, x0, y0 sind, multiplizieren Sie beide Seiten der Gleichung (c / d) und dann eine Menge spezieller Lösungen (c / d) x0 der ursprünglichen Gleichung , (c / d) y0 lautet die allgemeine Lösung der ursprünglichen Gleichung:
Lösung für diese Frage: Die in der Frage angegebene Kongruenzgleichung entspricht a * x + b * y = 1 (y ist eine ganze Zahl). Diese Frage hat garantiert eine Lösung, also gcd (a, b) | 1, dh gcd (a, b) = 1. Verwenden Sie den erweiterten euklidischen Algorithmus, um die spezielle Lösung x0, y0 zu finden. Die allgemeine Lösung von x ist x = x0 + k * b (k ist eine ganze Zahl). Beachten Sie, dass in der Frage die kleinste positive Ganzzahllösung erforderlich ist.
Code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a,b,x,y;
void exgcd(ll a,ll b,ll &x,ll &y)
{
if(!b) {x=1,y=0; return;}
exgcd(b,a%b,x,y);
ll z=x; x=y; y=z-(a/b)*y;
}
int main()
{
scanf("%lld%lld",&a,&b);
exgcd(a,b,x,y); //求出特解
x=(x%b+b)%b; //求出最小正整数解
printf("%lld\n",x);
return 0;
}