扩展欧几里得及中国剩余定理
Posted zerokei
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了扩展欧几里得及中国剩余定理相关的知识,希望对你有一定的参考价值。
Exgcd
扩展欧几里得
void exgcd(int a,int b,int &x,int &y){
if(!b){x=1,y=0;return;}
exgcd(b,a%b,x,y);b-=y*(a/b);
}
对于 (gcd(a,b)=g) ,(a imes k_1+b imes k_2 =g)
通过 (exgcd(a,b,x,y)) (k_1=x+k imes b)
对于 (gcd(a,b)=g) ,(a imes k_1+b imes k_2=C imes g)
通过 (exgcd(a,b,x,y)) (k_1 = x imes C+k imes b)
中国剩余定理
这里只讨论不互质的扩展情况
证明
现在有两条式子:
(X=a_1 imes k_1+b1)
(X=a_2 imes k_2+b_2)
可得恒等式
(a_1 imes k_1-a_2 imes k_2=b_2-b_1)
那么可以通过(exgcd)求出 (k_1) 的一组解
设合并上面两式的结果为 (X=a_3 imes k_3+b_3)
那么有 (a_3 imes k_3+b_3=a_1 imes k_1+b_1)
易得 (a_3=lcm(a_1,a_2))
则 (b_3=(a_1 imes k_1+b_1)\%a_3)
struct CRT{
static const int M=2888;
LL A[M],B[M];
int sz;
void insert(int a,int b){A[++sz]=a,B[sz]=b;}
LL gcd(LL a,LL b){return !b?a:gcd(b,a%b);}
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 Exgcd(LL A,LL B,LL C){
LL x,y;
exgcd(A,B,x,y);
return (x*C%B+B)%B;
}
LL Solve(){
FOR(i,1,sz-1){
LL C=B[i+1]-B[i],g=gcd(A[i],A[i+1]);
if(C%g)return -1;//无解
C/=g;
LL k1=Exgcd(A[i]/g,A[i+1]/g,C);
A[i+1]=A[i]/g*A[i+1];
B[i+1]=(A[i]*k1+B[i])%A[i+1];
}
return B[sz];
}
}CT;
以上是关于扩展欧几里得及中国剩余定理的主要内容,如果未能解决你的问题,请参考以下文章
hdu3579-Hello Kiki-(扩展欧几里得定理+中国剩余定理)