中国剩余定理模板

这个定理有两个版本,下面是互质版(非扩展版)的代码,具体讲解可以参考信息学竞赛数学一本通。做法大概就是:
把一个同余方程组:
x≡b1(mod m1)
x≡b2(mod m2)
x≡b3(mod m3)
……
x≡bn(mod mn)
转化成n个同余方程组:
x≡0(mod m1)
x≡0(mod m2)
……
x≡1(mod mi)
……
x≡0(mod mn)
每组解出来乘上对应mi加起来即可(每加一次都要模M,M=m1xm2x……xmn)
还可以去看看下面一篇博客:
CRT证明
FZU 1402是一道模板题,可以在vjudge上找到,代码如下:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
int n;
ll b[12],m[12];
ll exgcd(ll a,ll b,ll &x,ll &y) {
    if (!b) {
        x=1,y=0;
        return a;
    }
    ll d=exgcd(b,a%b,y,x);
    y-=(a/b)*x;
    return d;
}
ll crt() {
    ll mult=1,x,y,t,a=0;
    for (int i=1;i<=n;i++) mult*=m[i];
    for (int i=1;i<=n;i++) {
        t=mult/m[i];
        ll d=exgcd(m[i],t,x,y);
        y=(y%m[i]+m[i])%m[i];
        a=(a+y*t*b[i])%mult;
    }
    return (a%mult+mult)%mult;
}

int main() {
    while (~scanf("%d",&n)) {
        for (int i=1;i<=n;++i) scanf("%I64d%I64d",&m[i],&b[i]);
        printf("%I64d\n",crt());
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值