/*
中国剩余定理(孙子定理)
没想到又要学这玩意, 但是二刷还算轻松
这是用来解出一堆线性同余方程组同一解的定理
常见是这样的(求解x)
x ≡ a1 (mod m1)
x ≡ a2 (mod m2)
x ≡ a3 (mod m3)
...
x ≡ an (mod mn)
其中任意两个mi互质
M = m1 * m2 * m3 * ... * mn
Mi = M / mi
ti是Mi关于mi的逆元, 即Mi * ti ≡ 1 (mod mi)
那么x = Σ ai * Mi * ti (1 <= i <= n)
中国剩余定理是通过构造来得到一组解, 因此只需要证明可行即可
你可以尝试带入进去
比如这里带入第一个式子x ≡ a1 (mod m1)
因为x中除了第1项, 其他所有的ai * Mi * ti中的Mi里面都有m1这个因子, 那么其他项就可以被%m1完美消掉
只剩下第一项即, a1 * M1 * t1, 又因为Mi * ti ≡ 1 (mod mi), 那么M1 * t1 在%m1下就为1
那么就只剩下a1, 符合等式1,
对于其他的等式同理, 这就说明, 这是一个正确解
关于ti一定有解, Mi * ti ≡ 1 (mod mi), 因为Mi = M / mi, mi和其他mi互质, 因此(Mi, mi) = 1
通过裴蜀定理可得式子Mi*x + mi*y = 1, 而Mi * ti ≡ 1 (mod mi), 可以化成等式Mi * ti + mi*y = 1
那么Mi*x + mi*y = 1中的x就是ti, Mi*x + mi*y = 1存在, Mi * ti + mi*y = 1一定存在
x一定有解, 即ti一定有解, 那么ti就一定可以通过exgcd求出
值得一提的是M是所有mi的乘积, 那么通解应该也就知道了, 即x = x0 + k*M
我x加上k个M不影响每个mi取余它还是ai, 也就都是解,
(这里有多组解的原因也是, 有n个式子但能找出来n + 1个未知数(把同余方程列乘等式), 因此有无数解)
所以最小正整数解就是(x % M + M) % M
*/
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 11;
int n, m;
int A[N], B[N];
LL M = 1;
void exgcd(LL a, LL b, LL &x, LL &y)
{
if (b == 0)
{
x = 1;
y = 0;
return ;
}
exgcd(b, a % b, y, x);
y -= a / b * x;
}
int main()
{
cin >> n;
for (int i = 1; i <= n; i ++ )
{
cin >> A[i] >> B[i];
M *= A[i];
}
LL res = 0;
for (int i = 1; i <= n; i ++ )
{
LL Mi = M / A[i];
LL ti, x;
exgcd(Mi, A[i], ti, x);
res += ti * B[i] * Mi;
}
cout << (res % M + M) % M << endl;
return 0;
}
贴一个学习网站,课挺便宜的,可以试试
starrycoding