(扩展)中国剩余定理

(扩展)中国剩余定理

以前在大佬的教导下,学过推导过程(害,大一的事了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;
}
posted @ 2020-04-05 23:18  小饭hhh  阅读(97)  评论(0编辑  收藏  举报