擴充套件歐幾里得及中國剩餘定理
阿新 • • 發佈:2018-11-02
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\times k_1+b\times k_2 =g\)
通過 \(exgcd(a,b,x,y)\) \(k_1=x+k\times b\)
對於 \(gcd(a,b)=g\) ,\(a\times k_1+b\times k_2=C\times g\)
通過 \(exgcd(a,b,x,y)\) \(k_1 = x\times C+k\times b\)
中國剩餘定理
這裡只討論不互質的擴充套件情況
證明
現在有兩條式子:
\(X=a_1\times k_1+b1\)
\(X=a_2\times k_2+b_2\)
可得恆等式
\(a_1\times k_1-a_2\times k_2=b_2-b_1\)
那麼可以通過\(exgcd\)求出 \(k_1\) 的一組解
設合併上面兩式的結果為 \(X=a_3\times k_3+b_3\)
那麼有 \(a_3\times k_3+b_3=a_1\times k_1+b_1\)
易得 \(a_3=lcm(a_1,a_2)\)
則 \(b_3=(a_1\times 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;