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

扩展欧几里得及中国剩余定理

时间:2018-11-02 21:45:12      阅读:140      评论:0      收藏:0      [点我收藏+]

标签:const   struct   crt   lin   ati   time   结果   情况   void   

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;

扩展欧几里得及中国剩余定理

标签:const   struct   crt   lin   ati   time   结果   情况   void   

原文地址:https://www.cnblogs.com/Zerokei/p/9898218.html

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