中国の剰余定理
合同の方程式の問題を解決するが、それは拡張質的な変化のように見えますか?
合同式の問題
\ [X \当量A_1 \ MOD M_1 \]
\ [X \当量A_2 \ MOD M_2 \]
\ [\ドット\ドット\]
\ [X \当量A_N \ MOD m_n \]
上と同じ式を満たす解く\(Xの\)
中国剰余定理(CRT)
- 要件:モジュラス\(M_1、M_2、\ドット 、m_n \) 互いに素でなければならない(なぜ?)
- CRTは、金型内でこの方程式を教えてくれる\(M = M_1 * M_2 * \ドット* m_nの\) 独特の意味での解決策。
- CRTはまた、この解決策であることを教えてくれる\ [X \当量A_1 M_1 M_1 ^ { - 1} + A_2 M_2M_2 ^ { - 1} + \ドット+ A_N M_nM_n ^ { - 1} \ MOD M \] 前記\(M_I = M / M_I \) 、および\(M_I ^ { - 1} \) モジュロ\()M_I \の意味で逆元。
- \ [X = \和a_iを\ FRAC {M} {M_I} INV(\ FRAC {M} {M_I}、\、M_I)\]
- この溶液は、上記の式を満たすように検証することができる建設的な解決策です。
- なぜペアごとの品質?逆要件!
const int maxn=1000;
int a[maxn];
int m[maxn];
int CRT(int n){
int M=1;
int ans=0;
for(int i=1;i<=n;i++){
M*=m[i];
}
for(int i=1;i<=n;i++){
int x,y;
int Mi=M/m[i];
exgcd(Mi,m[i],x,y);
ans=(ans+a[i]*Mi*x)%M;
}
if(ans<0)ans+=M;
return ans;
}
拡張中国の剰余定理(exCRT)
- モジュラス\(M_1、M_2、\ドット 、m_n \) それは解くことができない総理かもしれません!
- 合同状況を方程式の2つだけの式を考えてみましょう。
- \ [X \当量C_1 \ MOD M_1 \]、 [X \当量C_2 \ MOD M_2 \] \
- \ [X = C_1 + m_1k_1 $、$ X = C_2 + m_2k_2 \]
- \ [C_1 + m_1k_1 = C_2 + m_2k_2 \]
- \ [m_1k_1 = C_2、C_1 + m_2k_2 \]
- 方程式の可解性のための必要十分条件である\ [\ GCD(M_1、M_2 )\、| \、(C_2-C_1)\]
- \ [\ FRAC {m_1k_1} {\ GCD(M_1、M_2)} = \ FRAC {C_2、C_1} {\ GCD(M_1、M_2)} + \ FRAC {m_2k_2} {\ GCD(M_1、M_2)} \]
- \ [\ FRAC {m_1k_1} {\ GCD(M_1、M_2)} \当量\ FRAC {C_2、C_1} {\ GCD(M_1、M_2)} \ MOD \ FRAC {M_2} {\ GCD(M_1、M_2)} \]
- \ [K_1 \当量INV(\ FRAC {M_1} {\ GCD(M_1、M_2)}、\ FRAC {M_2} {\ GCD(M_1、M_2)})* \ FRAC {C_2、C_1} {\ GCD(M_1 、M_2)} \ MOD \ FRAC {M_2} {\ GCD(M_1、M_2)} \]
- \(INV(b)は、 \) を表し\(\)型で\(B \)の意味で逆
- \ [K_1 = INV(\ FRAC {M_1} {\ GCD(M_1、M_2)}、\ FRAC {M_2} {\ GCD(M_1、M_2)})* \ FRAC {C_2、C_1} {\ GCD(M_1、 M_2)} + K * \ FRAC {M_2} {\ GCD(M_1、M_2)} \]
- 戻る\(X = C_1 + m_1k_1 \ )
- \ [X = C_1 + M_1 *(INV(\ FRAC {M_1} {\ GCD(M_1、M_2)}、\ FRAC {M_2} {\ GCD(M_1、M_2)})* \ FRAC {C_2、C_1} { \ GCD(M_1、M_2)} + K * \ FRAC {M_2} {\ GCD(M_1、M_2)})\]
- \ [X \当量C_1 + M_1 * INV(\ FRAC {M_1} {\ GCD(M_1、M_2)}、\ FRAC {M_2} {\ GCD(M_1、M_2)})* \ FRAC {C_2、C_1} { \ GCD(M_1、M_2)} \ MOD \ FRAC {m_1m_2} {\ GCD(M_1、M_2)} \]
- ここでは、同じ式の二つ以上の統合を完了しました!そこを形成(X \当量A \ MOD \ \ m)を
- 其中\ [A = C_1 + M_1 * INV(\ FRAC {M_1} {\ GCD(M_1、M_2)}、\ FRAC {M_2} {\ GCD(M_1、M_2)})* \ FRAC {C_2、C_1} { \ GCD(M_1、M_2)} \] \ [M = \ FRAC {m_1m_2} {\ GCD(M_1、M_2)} \]
- 繰り返し繰り返します!(二、プラス1、1、······)
const int maxn=1000;
int a[maxn];
int m[maxn];
int gcd(int a,int b){
return b?gcd(b,a%b):a;
}
int exgcd(int a,int b, int &x,int &y){
if(b==0){
x=1;
y=0;
return a;
}
int d=exgcd(b,a%b,x,y);
int tmp=x;
x=y;
y=tmp-a/b*y;
return d;
}
int inv(int a,int mod){
int x,y;
int d=exgcd(a,mod,x,y);
return d==1?(x%mod+mod)%mod:-1;
}
int exCRT(int n){
int m1, m2, c1, c2, d;
for(int i=2;i<=n;i++){
m1=m[i-1];//这里是与前一个进行合并
m2=m[i];
c1=a[i-1];
c2=a[i];
d=gcd(m1,m2);
if((c2-c1)%d!=0){
return -1;//无法合并
}
m[i]=m[i-1]*m[i]/d;//公式(倒数第二个)
a[i]=c1+m1*inv(m1/d,m2/d)%(m2/d)*(c2-c1)/d;//公式(倒数第二个)
a[i]=(a[i]%m[i]+m[i])%m[i];
}
return a[n];
}