1. 程式人生 > >(擴展)中國剩余定理

(擴展)中國剩余定理

拓展 ati 是我 col 中國剩余定理 span clas int sum

前言:

中國剩余定理($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; }

擴展中國剩余定理

擴展中國剩余定理可以用來解決模數不互質的情況

後序:

據說中國剩余定理好像很少會考

拓展中國剩余定理好像可以搞擴展盧卡斯定理

然而我並不會擴展盧卡斯

(擴展)中國剩余定理