您的位置:首页 > 其它

一个不用中国剩余定理求解线性同余方程组的方法。

2016-02-20 14:22 507 查看
  现在我们有x = b1(mod m1), x = b2(mod m2) ... x = bn(mod mn) 求解一个最小的使其满足上述方程,我们首先考虑x = b1 (mod m1), x = b2 (mod m2)这两个方程, 如果我们用这两个方程求出了一个解x0, 那么其一个解为x = x0 mod([m1, m2]), 通过这个办法我们将两个方程合成一个方程。 对于n个方程我们进行n-1次操作即可就出方程组的解。 现在思考如何将两个方程合并成为一个方程, x = b1(mod m1) => x = b1 + m1*y x = b2(mod m2) => x = b2 + m2*z 合并两式得到m1*y-m2*z=b2-b1,现在就可以用egcd求出一个解, 然后就可以顺利求出x了。代码如下:

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>

using namespace std;
typedef long long LL;

LL gcd(LL a, LL b)
{
if(!b) return a;
else return gcd(b, a%b);
}
LL lcm(LL a, LL b)
{
return a/gcd(a, b)*b;
}
void egcd(LL a, LL b, LL &d, LL &x, LL &y)
{
if(!b) { d=a; x=1; y=0; }
else { egcd(b, a%b, d, y, x); y -= x*(a/b); }
}

LL solve(LL bb[], LL m[], int len)    //返回最小解
{
for(int i=1; i<len; i++)
{
LL g, x, y;
LL a=m[0], b=-m[i], c=bb[i]-bb[0];
egcd(a, b, g, x, y);
if(c%g != 0) return -1;          //此时无解
x = c/g*x;
x = m[0]*x + bb[0];
m[0]=lcm(m[0], m[i]);
bb[0]=(x%m[0]+m[0])%m[0];
}
return bb[0];
}

int main()
{
int len;
LL bb[100], m[100];
cin>>len;
for(int i=0; i<len; i++)
{
cin>>bb[i]>>m[i];
}
cout<<solve(bb, m, len)<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: