ExCRT笔记
问题
求满足:
的的值。ExCRT
当互素的时候显然可以使用中国剩余定理(CRT)解决,时间复杂度为。
考虑不互素的情况,假设已经解决了前个方程,得到的解为,。
那么我们考虑解决
易证得到的解不会再和前个解产生冲突。稍微移项一下:
用ExGCD解出即可。这套方法称为ExCRT(拓展中国剩余定理),复杂度依旧是。全面优于CRT。
代码:
#include <cstdio>
using namespace std;
typedef long long ll;
const int N = 100010;
int n;
ll a[N], b[N];
ll exgcd(ll a, ll b, ll &x, ll &y) {
if (b == 0) return x = 1, y = 0, a;
ll d = exgcd(b, a % b, y, x);
return y -= a / b * x, d;
}
ll smul(ll x, ll y, ll mod) {
if (y < 0) return -qmul(x, -y, mod);
ll ret = 0;
for (; y; y >>= 1) {
if (y & 1) ret = (ret + x) % mod;
x = (x + x) % mod;
}
return ret;
}
ll excrt() {
ll lcm = a[1], t = b[1], x, y;
for (int i = 2; i <= n; i++) {
ll d = exgcd(lcm, a[i], x, y);
x = smul(x, (b[i] - t) / d, a[i]);
t += x * lcm;
lcm = lcm / d * a[i];
t = (t % lcm + lcm) % lcm;
}
return t;
}
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++) scanf("%lld%lld", &a[i], &b[i]);
printf("%lld\n", excrt());
return 0;
}