码迷,mamicode.com
首页 > 其他好文 > 详细

中国剩余定理

时间:2019-03-18 14:03:07      阅读:219      评论:0      收藏:0      [点我收藏+]

标签:lan   pre   coder   code   get   add   ++   并且   for   

前言:

中国剩余定理($CRT$),也称孙子定理,原文如下:

啊“有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二。问物几何?”

很明显这是一个同余方程组,于是我们就可以用中国剩余定理求解

正文:

中国剩余定理

它可以用于求解模数两两互质时的同余方程组

设 $b_1,b_2,\ldots,b_k$ 两两互质

则同余方程组 $\begin{cases} x\equiv a_1\ (mod\ b_1) \\ x\equiv a_2\ (mod\ b_2) \\ \qquad\dots \\ x\equiv a_k\ (mod\ b_k) \end{cases}$ 有整数解

并且在 $mod\ lcm=\prod_{i=1}^{k}b_i$ 意义下有唯一解

为 $x=\sum_{i=1}^ka_ileft_iinv(left_i)\%lcm$

其中 $left_i=\dfrac{lcm}{b_i}$ ,$inv(left_i)$ 为 $left_i\ mod\ b_i$ 意义下的逆元

同时 $CRT$ 一般会配合龟速乘,防止乘起来会爆 $long\ long$

typedef long long ll;

void exgcd(ll a,ll b,ll &x,ll &y)
{
    if(!b)
    {
        x=1,y=0;
        return;
    }
    exgcd(b,a%b,y,x);
    y-=a/b*x;
}

ll qmul(ll a,ll b,ll p)
{
    ll ans=0,base=a%p;
    while(b)
    {
        if(b&1) ans=(ans+base)%p;
        base=(base+base)%p;
        b>>=1;
    }
    return ans;
}

ll CRT(int n,ll *a,ll *b)
{
    ll ans=0,lcm=1;
    for(int i=1;i<=n;i++)
        lcm*=b[i];
    for(int i=1;i<=n;i++)
    {
        ll inv,k;
        ll left=lcm/b[i];
        exgcd(left,b[i],inv,k);
        inv=(inv%b[i]+b[i])%b[i];
        ans=(ans+qmul(qmul(a[i],left,lcm),inv,lcm))%lcm;
    }
    return (ans+lcm)%lcm;
}

扩展中国剩余定理

扩展中国剩余定理可以用来解决模数不互质的情况

后序:

据说中国剩余定理好像很少会考

拓展中国剩余定理好像可以搞扩展卢卡斯定理

然而我并不会扩展卢卡斯

中国剩余定理

标签:lan   pre   coder   code   get   add   ++   并且   for   

原文地址:https://www.cnblogs.com/Vscoder/p/10551544.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!