扩展欧几里得

扩展欧几里得即求方程 ax + by = gcd(a,b) 的整数解的算法。常用来求解逆元,即 ax = 1(mod b)  -> ax % b = 1  -> ax - by = 1; 令b = -b,即

ax + by = 1,当a,b互质时有 ax + by = gcd(a,b);

求解过程:

根据欧几里得算法,当b!=0时,gcd(a,b) == gcd(b,a%b);

所以 ax + by = gcd(b,a%b); -> bx` + (a%b)y` = gcd(b,a%b);

联立方程 ax + by = (a%b)*y` + bx`;

ax + by = (a - a/b*b) * y` + bx`;

ax + by = ay` - a/b*b * y` + bx`;

ax + by = ay` + b(x`- a/b * y`);

对应项的 x = y`,y = (x` - a/b * y`);

令A = b,B = a%b; Ax`` + By`` = gcd(A,B);

由此不断递推,直到B = 0;则Ax = gcd(A,0) = A;

x`` = 1;y``为任意值,这里我们赋为0;

则可根据x = y`,y = (x` - a/b * y`),得到上层解从而解得方程

 

#include <iostream>
#include <cstdio>
using namespace std;
long long extend_gcd(long long a,long long b,long long &x,long long &y){
	if(a ==0 && b == 0)return -1;
	if(b == 0){x = 1;y = 0;return a;}
	long long d = extend_gcd(b,a%b,y,x);// d 表示 a,b的gcd; 现在的y = x`,x = y`;
	y -= a/b*x;
	return d;
}
long long mod_reverse(long long a,long long n){
	long long x,y;
	long long d =extend_gcd(a,n,x,y);
	if(d == 1)return (x%n+n)%n; // 保证最小正整数解;
	else return -1; 
}
int main(){
	long long a,n;
	while(cin>>a>>n){
		cout << mod_reverse(a,n) << endl; 
	}
	return 0;
} 

 

posted on 2019-04-10 15:25  hbzCoder  阅读(90)  评论(0编辑  收藏  举报

导航