中国剩余定理
概念
定理介绍和证明
例题
求解模线性方程组,形如:
a ≡ B[1](mod W[1])
a ≡ B[2](mod W[2])
…
…
a ≡ B[n](mod W[n])
W,B已知,W[i]>0 且所有W互质,求a (最小正整数解)。
代码实现
#include <iostream>
using namespace std;
//中国剩余定理
//所有模数互质
typedef long long ll;
int W[51],B[51];
ll exgcd(ll a, ll b, ll &x, ll &y)//扩欧算法
{
if (!b)
{
x = 1,y = 0;
return a;
}
ll gcd = exgcd(b, a % b, x, y);
ll tmp = x;
x = y;
y = tmp - a / b * y;
return gcd;
}
int China(int * w, int * b, int k)
{
ll x, y , a = 0;
int m;
ll N = 1;
for(int i = 1; i < k + 1; i ++) N *= w[i];
for(int i = 1; i < k + 1; i ++)
{
m = N / w[i];
exgcd(w[i],m,x,y);
a = (a + y *m * b[i]) % N;
}
return (a + N) % N;
}
int main()
{
int n;
cin >> n;//方程数
for(int i = 1; i <= n; i ++)
cin >> W[i] >> B[i];
int res = China(W,B,n);
cout << res <<endl;
return 0;
}
解一般意义同余方程通用方案(模数不一定两两互素)
求解方案论述
例题
代码实现
#include <iostream>
using namespace std;
typedef long long ll;
ll exgcd(ll a, ll b, ll &x, ll &y)
{
if (!b)
{
x = 1; y = 0;
return a;
}
ll d = exgcd(b, a % b, y, x);
y -= (a/b) * x;
return d;
}
int main()
{
int n;
cin >> n;
bool flag = true;
ll a1, m1;
cin >> a1 >> m1;
for(int i = 0; i < n - 1; i ++)
{
ll a2, m2;
cin >> a2 >> m2;
ll k1, k2;
ll d = exgcd(a1,a2,k1,k2);
if((m2 - m1) % d)
{
flag = false;
break;
}
k1 *= (m2 - m1) / d;
k1 = (k1 % a2 +a2) % a2;//adjust to minimal
m1 = a1 * k1 + m1;//特解
a1 = a1 / d * a2;// X = A1 K + M1
}
if(flag)
{
cout << (m1 % a1 + a1) % a1 <<endl;
}
else puts("-1");
return 0;
}