中国剩余定理(孙子定理)

  • 内容:在一千多年前的《孙子算经》中,有这样一道算术题:“今有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二,问物几何?”按照今天的话来说:一个数除以3余2,除以5余3,除以7余2,求这个数。这样的问题,也有人称为“韩信点兵”.它形成了一类问题,也就是初等数论中的解同余式
  • 定理一:几个数相加,如果存在一个数,不能被a整除,那么它们的和就不能被a整除。
  • 定理二:两个数不能整除,若除数扩大(或缩小)几倍,而被除数不变,这其商和余数也同时扩大(或缩小)相同的倍数(余数必小于除数)。

步骤:

1、求出最小公倍数

 lcm=3*5*7=105

2求各个数所对应的基础数

(1)105÷3=35

 35÷3=11......2 //基础数35

(2)105÷5=21

 21÷5=4......1

 定理2把1扩大3倍得到3,那么被除数也扩大3倍,得到21*3=63//基础数63

3105÷7=15

15÷7=2......1

定理2把1扩大2倍得到2,那么被除数也扩大2倍,得到15*2=30//基础数30

把得到的基础数加和(注意:基础数不一定就是正数)

35+63+30=128

4减去最小公倍数lcm(在比最小公倍数大的情况下)

x=128-105=23

模板

/*long long gcd(LL a,LL b)
{
    return b==0?a:gcd(b,a%b);
}*/
#include<cstdio>
#define ll long long
//扩展欧几里得算法 
void gcd(ll a,ll b,ll &d,ll &x,ll &y)
{
    if(b==0){
        d=a;
        x=1,y=0;
    }
    else{//else不能省略 
        gcd(b,a%b,d,y,x);
        y-=(a/b)*x;
    }
}
//中国剩余定理
ll China(int n,ll *m,ll *a)
{
    ll M=1,d,y,x=0;
    for(int i=0;i<n;i++) M*=m[i];
    for(int i=0;i<n;i++){
        ll w=M/m[i];
        gcd(m[i],w,d,d,y);
        x=(x+y*w*a[i])%M;
    }
    return (x+M)%M;
}
ll m[15],a[15];
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
        scanf("%lld%lld",&m[i],&a[i]);
    printf("%lld",China(n,m,a));
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值