扩展gcd以及同余方程ax=b(mod M)

105 篇文章 0 订阅
57 篇文章 0 订阅

关于扩展gcd其实没有必要搞懂,背下来就好了如果不会的自行学习

对于方程ax=b(mod M),我们可以将其化简成为ax+My=b,让后用扩展gcd求解

当b|r=gcd(a,M)时,方程有r个解,否则无解,对于有解的情况,每个解为用gcd求出的x乘上b/r+k*(M/r)

int extgcd(int a,int b,int& x,int& y){
	if(b){
		int r=extgcd(b,a%b,y,x);
		y-=x*(a/b); return r;
	} else { x=1; y=0; return a; }
}
int solve(int a,int b,int M){
	int x,y,r=extgcd(A,M,x,y);
	if(B%r) return -1; else x=(x+M)%M*b/r;
	// return x; 这个是返回通解
	return x%(M/r); //返回最小解
} 


  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在C++中,可以使用扩展欧几里得算法来解决同余方程组,以下是一个实现示例: ```c++ #include <iostream> #include <vector> using namespace std; int gcd(int a, int b, int& x, int& y) { if (b == 0) { x = 1; y = 0; return a; } int d = gcd(b, a % b, y, x); y -= a / b * x; return d; } int mod_inverse(int a, int m) { int x, y; gcd(a, m, x, y); return (x % m + m) % m; } int solve_congruences(const vector<int>& a, const vector<int>& m) { int x = 0, M = 1; for (int i = 0; i < m.size(); i++) { int Mi = M / gcd(M, m[i]) * m[i]; int ti = mod_inverse(Mi / m[i], m[i]); x = (x + a[i] * ti * Mi) % M; M = Mi; } return (x + M) % M; } int main() { vector<int> a = {2, 3, 2}; vector<int> m = {3, 5, 7}; int x = solve_congruences(a, m); cout << "x = " << x << endl; // 输出 x = 23 return 0; } ``` 其中,“gcd”函数用于计算最大公约数和扩展欧几里得算法,它返回最大公约数d,并通过引用参数x和y返回贝祖等式ax + by = d 的解。这里使用递归实现,将x和y的顺序颠倒以便计算ti时使用。 “mod_inverse”函数用于计算a模m的逆元,即满足ax ≡ 1 (mod m)的x。 “solve_congruences”函数实现了中国剩余定理。首先计算M = m1 * m2 * ... * mn,然后对于每个同余方程,计算Mi = M / mi,以及它在模mi下的逆元ti,最后计算解x = Σ(ai * ti * Mi) (mod M)。注意到这里使用了M逆元而非mi逆元,因为后者可能不存在。 最后在主函数中输入系数和模数,调用solve_congruences函数求解同余方程组,并输出结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值