中国剩余定理=.=

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

前置知识:逆元,取模运算。

先说说这个定理可以干什么吧。

例题:设一个非负整数X,X%3的值为2,X%5的值为3,X%7的值为6。那么X的值是多少??

X\equiv2%3

X\equiv 3%5

X\equiv 6%7

计算:

1.先求出3,5,7的公倍数M,M也就是105.

 

2.对于第一个式子,设V_{1}=M/3,V_{1}也就是35.(别问为什么这么蠢的在这里绕,耐心看),再求V_{1}在模3下的逆元 T_{1}

(逆元就是在模一个数情况下,乘积为1的的数,比如:在对5取模的情况下,2即为3的逆元,2*3等于6,再对5取余,就是1了

是不是很像普通情况下的倒数)。

那么现在V_{1}​​​​​​​*T_{1}再对3取模的值就是1了,那么2*V_{1}​​​​​​​*T_{1}对3取模就是2。再看,现在2*V_{1}​​​​​​​*T_{1}是不是就是第一式子的解了。那么对于其他的

式子来说呢?这个值对其他式子的模数计算,发现会等于0,因为最开始的时候计算M就是那些模数乘出来的啊,而V_{1}​​​​​​​是除去了当前式子的模数,这时候V_{1}还是其他式子 模数的倍数。

 

 

3.我们对每一个式子都进行上述的运算,每次都会得到一个a_{i}*V_{i}*T_{i}  ,  a_{i}就是每个式子取模剩下的数,比如第一个式子就是2。

V_{i}就是公倍数(所有式子的模数)M除以当前式子的模数的值。T_{i}则是逆元。然后把所有的a_{i}*V_{i}*T_{i} 加起来得到sum,sum就是一个我们

想要的值,怎么稀里糊涂就算完了??看上面的红字,每一次算出来的a_{i}*V_{i}*T_{i} 对于其它式子来说,在对其它的式子的模数取模之后,就变成0了。所以sum即是所有式子的解,由于要求最小的非负整数解,所以sum再对M取模。

注意:中国剩余定理的使用前提是每个式子中的所有模数都需要互质,比如上面式子中的3,5,7就是互质的。

想知道为什么??下一篇扩展中国剩余定理再说了。

最后,代码:

#include<bits/stdc++.h>
using namespace std;
int n;
long long int arr[20];
long long int m[20];
long long int mod;
long long int quick_multiple(long long int n,long long int base)
{
    if(n<0)
    {
        base*=-1;
        n*=-1;
    }
    long long int ans=0;
    while(n)
    {
        if(n&1)
        {
            ans+=base;
            ans%=mod;
        }
        n>>=1;
        base+=base;
        base%=mod;
    }
    return ans;
}
void exgcd(long long int a,long long int b,long long int &x,long long int &y)
{
    if(!b)
    {
        x=1;
        y=0;
        return ;
    }
    exgcd(b,a%b,y,x);
    y-=a/b*x;
}
long long int CRT()
{
    long long int M=1;
    long long int ans=0;
    long long int x,y,t;
    for(int i=0;i<n;++i)
        M*=m[i];
        mod=M;
    for(int i=0;i<n;++i)
    {
        t=M/m[i];
        exgcd(t,m[i],x,y);
        ans=(ans+quick_multiple(quick_multiple(arr[i],x),t))%M;
    }
    return (ans+M)%M;
}
int main()
{
    cin>>n;
    for(int i=0;i<n;++i)
        cin>>arr[i];
    for(int i=0;i<n;++i)
        cin>>m[i];
    cout<<CRT()<<endl;
    return 0;
}

 

 

 

 

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值