扩展欧几里得算法

 定理:对不全为0的数a,b,存在整数x,y使得 ax+by=gcd(a,b)

可使用扩展欧几里得算法来求解x,y

/扩展欧几里德算法,求解ax+by=gcd(a,b)系数
void extendEuclid(int a, int b, int &d, int &x, int&y){
	if (!b){ d = a; x = 1; y = 0; }
	else{ extendEuclid(b, a%b, d, y, x); y -= x*(a / b); }
}

 1.求解二元不定方程 ax+by=n

   结论:方程有解得充分必要条件是gcd(a,b)|n.若(x0,y0)是方程的一组解,则方程全部解可以表示为:x=x0+b*k,y=y0-a*k, (k为任意整数)

//求ax+by=n的一个解
//所有解为(x0+t*b,y0-t*a),t是任意整数 int solveLiner(int a, int b, int n,int&x,int&y){ int d; extendEuclid(a, b, d, x, y); if (n%d)return 0; //无解 x = (n / d)*x; y = (n / d)*y; return 1; }

 2求解模线性方程 ax≡b(mod n)(n>0)

  首先解释 a≡b(mod n)的含义是:a和b关于n同余,即 a mod n= b mod n;充要条件是n|(a-b)。于是ax≡b(mod n) 等价于 n|(ax-b),这说明:ax-b=kn,即为ax-kn=b

这与上面提到的求解不定方程完全相同,当且仅当gcd(a,n)|b时方程才有解。

  定理:方程ax≡b(mod n)或者有gcd(a,n)个不同的解,或者无解,有解充要条件是gcd(a,n)|b.

  特别的,对于b==1时候,上述方程变为ax≡1(mod n),称为a关于模n的逆,类似于实数中“倒数的概念”,由上面可知当且仅当gcd(a,n)=1时,a的逆才存在。

//ax≡b(mod n)n>0
void mod_equation_solver(int a, int b, int n){
	int d, x, y, x0;
	extendEuclid(a,n,d,x, y);
	if (b%d)printf("no answer");
	else{
		x0 = x*(b / d) % n;  //x0是基础解
		for (int i = 0; i < d; i++)
			printf("%d
", (x0 + i*(n / d)) % n);
	}
}

 

//逆元ax≡1(mod n)
int Inv(int a, int n){
	int d, x, y;
	extendEuclid(a, n, d, x, y);
	if (d == 1)return (x%n+n)%n; else return -1;
}

  

原文地址:https://www.cnblogs.com/td15980891505/p/5800404.html