(扩展)中国剩余定理
(扩展)中国剩余定理
以前在大佬的教导下,学过推导过程(害,大一的事了https://www.cnblogs.com/fanshhh/p/10506660.html
然后发现一直没写过代码(QAQ我以为我写过的
P1495 【模板】中国剩余定理(CRT)/曹冲养猪
模数互质的
#include <cstdio>
typedef long long LL;
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;
}
LL inv(LL a, LL p) {
LL x, y;
exgcd(a, p, x, y);
return (x % p + p) % p;
}
int main() {
int n;
scanf("%d", &n);
LL sum = 1, a[15], b[15];
for(int i = 0; i < n; i++) {
scanf("%lld %lld", &a[i], &b[i]);
sum *= a[i];
}
LL ans = 0;
for(int i = 0; i < n; i++) {
ans = (ans + (sum / a[i]) * b[i] * inv(sum / a[i], a[i])) % sum;
}
printf("%lld\n", ans % sum);
return 0;
}
P4777 【模板】扩展中国剩余定理(EXCRT)
模数不互质的
#include <cstdio>
typedef long long LL;
void exgcd(LL a, LL b, LL &d, LL &x, LL &y) {
if(b == 0) {
d = a;
x = 1;
y = 0;
return ;
}
exgcd(b, a % b, d, y, x);
y -= a / b * x;
}
LL power_mod(LL a, LL b, LL p) {
LL ret = 0;
while(b) {
if(b & 1) ret = (ret + a) % p;
a = (a + a) % p;
b >>= 1;
}
return ret;
}
int main() {
int n;
scanf("%d", &n);
LL sum = 1, a[100010], b[100010];
for(int i = 0; i < n; i++) {
scanf("%lld %lld", &a[i], &b[i]);
}
LL aa = a[0], bb = b[0];
for(int i = 1; i < n; i++) {
LL x, y, d, c = (b[i] - bb % a[i] + a[i]) % a[i];
exgcd(aa, a[i], d, x, y);
LL bg = a[i] / d;
x = power_mod(x, c / d, bg);
bb += aa * x;
aa *= bg;
bb = (bb % aa + aa) % aa;
}
printf("%lld\n", (bb % aa + aa) % aa);
return 0;
}