[Problem solution] Luogu P1082 [NOIP2012] Congruence equation (expanded Euclidean algorithm detailed explanation)

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

Guess you like

Origin blog.csdn.net/zjgmartin/article/details/108415336