Go to: My own blog
topic
Luogu P1082 Congruence Equation
answer
Define gcd(a,b) as the Greatest Common Divisor of a,b.
According to Euclid's theorem:
In particular: gcd(a,0)=a
From the theorem of Pei Shu:
Extended Euclidean algorithm: suppose a*x+b*y=gcd(a,b)
1. When b=0, gcd(a,b)=a, the solution is x=1, y=0
2.b!=0, suppose
It can be equivalently transformed into:
Compared with the equation a*x+b*y=gcd(a,b), we get: x=y',y=x'-(a/b)*y', repeat the operation, recursively change x, y to find Get a set of special solutions x0, y0.
Extension (no proof in this article): Let d=gcd(a,b), for the more general equation a*x+b*y=c, there is a solution if and only if d|c. Assuming that a set of special solutions obtained from a*x+b*y=d are x0, y0, multiply both sides of the equation (c/d), and then a set of special solutions (c/d) x0 of the original equation ,(c/d)y0, the general solution of the original equation is:
Solution to this question: The congruence equation given in the question is equivalent to a*x+b*y=1 (y is an integer), this question is guaranteed to have a solution, so gcd(a,b)|1, that is, gcd(a, b)=1. Use the extended Euclidean algorithm to find the special solution x0, y0, the general solution of x is x=x0+k*b (k is an integer). Note that the smallest positive integer solution is required in the question.
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;
}