码迷,mamicode.com
首页 > 其他好文 > 详细

线性同余方程

时间:2018-04-22 17:21:10      阅读:176      评论:0      收藏:0      [点我收藏+]

标签:根据   欧几里得算法   要求   turn   扩展欧几里得   整数   最小   a*   就是   

如何解方程a*x≡b(mod m)呢?因为a*x-b|m, 故令a*x-b=-y*m,即a*x+m*y=b。根据Bezout定理,该方程有解当且仅当gcd(a,m)|b。我们把等式两边同乘以gcd(a,m)/b,得到a*x0+m*y0=gcd(a, m)。这个方程可以用扩展欧几里得算法求得得到x0。等式是怎么乘的,就再把它除回来,也就是x=x0*b/gcd(a,m)。关于方程的通解,a*x+k*lcm(a,m)+m*y-k*lcm(a,m)=b,lcm(a,m)=a*m/gcd(a,m),也就是a*(x+k*m/gcd(a,m))+m*(y+k*a/gcd(a,m))=b,所以方程的通解为所有与x同余m/gcd(a,m)的数。若要求最小正整数解,令p=m/gcd(a,m),然后x=(x%p+p)%p即可。

ll Exgcd(ll a, ll b, ll &x, ll &y)
{
	if (b == 0)
	{
		x = 1;
		y = 0;
		return a;
	}
	ll d = Exgcd(b, a%b, x, y);
	ll tx = x;
	x = y;
	y = tx - (a / b) * y;
	return d;
}

ll Gcd(ll a, ll b)
{
	return b ? Gcd(b, a%b) : a;
}

ll Eq(ll a, ll b, ll m)
{
	ll gcd = Gcd(a, m);
	if (b%gcd)
		return -1;
	ll x, y;
	Exgcd(a, m, x, y);
	x = x * b / gcd;
	ll p = m / gcd;
	return (x%p+p) % p;
}

  

线性同余方程

标签:根据   欧几里得算法   要求   turn   扩展欧几里得   整数   最小   a*   就是   

原文地址:https://www.cnblogs.com/headboy2002/p/8908090.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!