中国剩余定理 学习笔记

前言:先食用同余,会有更好的学习效果。

--------------------

中国剩余定理:若$m_{1},m_{2}...m_{n}$是两两互质的正整数,$M=\prod_{i=1}^{n} m_{i},M_{i}=M/M_{i}$,$t_{i}$是线性同余方程$M_{i}t_{i}\equiv 1(mod m_{i})$的一个解。对于任意的$n$个整数$a_{1},a_{2}...a_{n}$,则同余方程组:

$x\equiv a_{1}(mod m_{1})$

$x\equiv a_{2}(mod m_{2})$

$\cdots$

$x\equiv a_{n}(mod m_{n})$

有整数解,方程组的解为$x=a_{1}M_{1}t_{1}+a_{2}M_{2}t_{2}+...+a_{n}M_{n}t_{n}$。并且在模$M$的意义下有唯一解。

证明:

因为$M_{i}=M/m_{i}$是除$m_{i}$之外所有模数的倍数,所以对于任意$k\ne i$,$a_{i}M_{i}t_{i}\equiv 0(mod m_{i})$。又因为$a_{i}M_{i}t_{i}\equiv a_{i}(mod m_{i})$(由定义得),所以$x=\sum_{i=1}^{n}a_{i}M_{i}t_{i}$,原方程组成立。

--------------------

【模板】曹冲称象

题目链接

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
LL a[11],b[11],N,M=1,Ans=0;
void Read()
{
    cin>>N;
    for (LL i=1;i<=N;i++)
    {
        cin>>a[i]>>b[i];
        M*=a[i];
    }
}
void exgcd(LL a,LL b,LL &d,LL &x,LL &y)
{
    if (!b){x=1;y=0;d=a;}
    else{
        exgcd(b,a%b,d,x,y);
        LL t=x;x=y;y=t-a/b*y; 
    }    
} 
void intchina()
{
    LL Mi,x,y,i,d;
    for (i=1;i<=N;i++)
    {
        Mi=M/a[i];
        exgcd(Mi,a[i],d,x,y);
        Ans=((Ans+Mi*x*b[i])%M+M)%M;
    }
    cout<<Ans<<endl;
}
int main()
{
    Read();
    intchina();
    return 0;
}

 

posted @ 2020-05-14 16:47  我亦如此向往  阅读(167)  评论(0编辑  收藏  举报