中国剩余定理
https://www.luogu.com.cn/problem/P1495
题意概述:给定一组同余方程:
\[x \equiv b_i \pmod {a_i}
\]
其中所有 \(a_i\) 互质,求最小正整数解。
考虑构造一组 \(c\),使得 \(c_i\) 模 \(a_i\) 为 \(b_i\),模其他 \(a_j\) 为 \(0\),则 \(x = \sum{c_i}\) 为一个解。
构造方式如下:
令 $d = \prod{a_i} $,则 $c_i = d/a_i \cdot b_i \cdot ((d/a_i)^{-1} \pmod{a_i}) $。
首先因为 \(c_i\) 有 \(d/a_i\) 的因子,模其他 \(a_j\) 为 \(0\) 是显然的;其次 \(d/a_i \cdot ((d/a_i)^{-1} \pmod{a_i})\) 为 \(1\),于是 \(c_i\) 在模 \(a_i\) 意义下为 \(b_i\),因此构造条件满足。
这样得到的 \(x\) 就是满足同余方程的解,\(x\) 在模 \(d\) 意义下的值就是最小整数解。实现上,由于 \(a_i\) 不一定为质数,需要用拓展欧几里得算法求逆元,注意开 i128 和对 \(d\) 取模。
//author:kzssCCC
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using i128 = __int128;
void solve(){
int n;
cin >> n;
vector<ll> a(n+1),b(n+1);
ll d = 1;
for (int i=1;i<=n;i++){
cin >> a[i] >> b[i];
d *= a[i];
}
auto cal_inv = [&](ll a,ll b){
ll x,y;
function<void(ll,ll)> exgcd = [&](ll a,ll b){
if (b==0){
x = 1;
y = 0;
}
else{
exgcd(b,a%b);
ll tx = x;
ll ty = y;
x = y;
y = tx-a/b*ty;
}
};
exgcd(a,b);
return (x%b+b)%b;
};
ll x = 0;
for (int i=1;i<=n;i++){
x = (x+(i128)d/a[i]%d*b[i]%d*cal_inv(d/a[i],a[i])%d)%d;
}
cout << x << '\n';
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
int t = 1;
// cin >> t;
while (t--) solve();
return 0;
}

浙公网安备 33010602011771号