Extended Euclidean algorithm--exgcd (P1082 congruence equation)

exgcd is used to find a ∗ x + b ∗ y = gcd (a, b) a * x + b * y = gcd(a, b)ax+band=gcd(a,b ) a set of solutions{x, y} \{x, y\}{ x,y } method. a ∗ x + b ∗ y = gcd (a, b) − − − 1 a*x +b*y = gcd(a, b)---1ax+band=gcd(a,b)1 b ∗ x + ( a % b ) ∗ y = g c d ( b , a % b ) − − − 2 b*x+(a \% b)*y = gcd(b, a\%b)---2 bx+(a%b)and=gcd(b,a%b)2 a % b = a − [ a / b ] ∗ b − − − 3 a\%b = a-[a/b]*b---3 a%b=a[a/b]b3 brings 3 into 2 => brings 3 into 2 =>The three band into 2=> b ∗ x + ( a − [ a / b ] ∗ b ) ∗ y = g c d ( b , a % b ) − − − 4 b*x+(a-[a/b]*b)*y = gcd(b, a\%b)---4 bx+(a[a/b]b)and=gcd(b,a%b)4 deform 4 => deform 4 =>The four variable -shape=> a ∗ y + b ∗ ( x − [ a / b ] ∗ y ) = g c d ( b , a % b ) − − − 5 a*y+b*(x-[a/b]*y) = gcd(b, a\%b)---5 aand+b(x[a/b]and )=gcd(b,a%b)It can be seen that 5 becomes the form of 1, and it can be solved recursively. It can be seen that it becomes the form of 1, and it can be solved recursively.May be to look at the turn into the one of the form type , it may be in a handover normalized seeking solution of . Until b = 0, a = gcd, a ∗ x + b ∗ y = gcd => Until b = 0, a = gcd, a*x+b*y = gcd=>Straight to b=0 o'clock , a=gcdax+band=gcd=> Special solution x = 1, y = 0, and then reverse the initial solution of a and b; Special solution x = 1, y = 0, and then reverse the initial solution of a, b;Special solution x=1 and=0 , then the re- trans pushed most open start A , B of the solution ;

int exgcd(int a, int b, int &x, int &y) {
    
    
	if(!b) {
    
    
		x = 1, y = 0;
		return a;
	}
	int gcd = exgcd(b, a%b, x, y);
	//上面部分和求最大公因子一样。
	//下面部分就是证明中式子5的x, y变换。
	//
	int temp = x; 
	x = y;
	y = temp - a/b * y;
	return gcd;
}

P1082 Congruence equation

Question: Given a, pa, pa,p , find satisfyinga ∗ x = 1 (mod p) a*x=1(mod~p)ax=1 ( m o d p )  x;
to use the above exgcd, we first seta ∗ x = 1 (mod p) a*x=1(mod~p)ax=1 ( m o d p )  becomes a form.
a ∗ x = 1 (mod p) = a ∗ x + p ∗ y = 1 a*x=1(mod~p)~=~a*x+p*y=1ax=1(mod p) = ax+pand=1 . In this way, we convert to finding x, y. But in exgcda ∗ x + p ∗ ya*x+p*yax+py is equal togcd (a, b) gcd(a, b)gcd(a,b ) , so 1 must be divisible bygcd (a, b) gcd(a, b)gcd(a,b ) . This is equivalent togcd (a, b) = 1 gcd(a, b)=1gcd(a,b)=1 , a and b are relatively prime. The question says there must be a solution, and the non-existent situation is not considered.
Because x may be less than 0,(x+m)%mmake x greater than 0.

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
void exgcd(ll a, ll b, ll &x, ll &y) {
    
    
	if(!b) {
    
    
		x = 1, y = 0;
		return ;
	}
	exgcd(b, a%b, x, y);
	ll temp = x;
	x = y;
	y = temp - a/b*y;
}
int main() {
    
     
	ll n, m, x, y;
	scanf("%lld%lld", &n, &m);
	exgcd(n, m, x, y);
	printf("%lld", (x+m)%m);
	return -0;
} 

Guess you like

Origin blog.csdn.net/weixin_45363113/article/details/106769317
Recommended