中国剩余定理的解析及记忆(扩展欧几里得算法的运用)

中国剩余定理
简单解释一下:
设m1,m2,m3....mk两两互素,下面称为同余方程组
x=a1*k1+m1;
x=a2*k2+m2;
x=a3*k3+m3;
.....
其中a1,a2,a3...是已知的,m1,m2,m3..也是已知的
要求x,但可以不用求系数k
原理:
x会存在整数解,
且在M=m1*m2*m3*...*mk下的解是唯一的
即x=(a1*M1*M1^-1+a2*M2*M2^-1+..+ak*Mk*Mk^-1)mod M
其中Mi=M/mi,也就是除去mi的总积,
而Mi^-1是Mi mod mi的逆元,

简单来说:
求Mi*x = 1( mod mi) 的x值,就是Mi的逆元
也就是满足Mi*x+mi*y=1的x值;因为mi彼此互素,所以Mi与mi也互素,所以最大公约数为1,直接代入扩展欧几里得函数求x。
int CRT(int a[],int m[],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];  
        extend_gcd(Mi, m[i], x, y);  
        ans = (ans + Mi * x * a[i]) % M;  //最终ans=(a1*M1*M1^-1+a2*M2*M2^-1+..+ak*Mk*Mk^-1)mod M
    }  
    if(ans < 0) ans += M;  //有可能ans<0,因为系数有可能为负数,再加一个M就可以了
    return ans;  
}

下面这个就是扩展欧几里得算法,上面有用到,实际上就是求能使ax+by=d成立的x和y以及d(是a,b最小公约数),其中a,b已知
但实际上题目给我们的方程一般右边是d的倍数,所以用这个方法得到的x,y并不一定是题目的解,还要都乘以这个倍数.
long long extend_gcd(long long a,long long b,long long &x,long long &y)
{
if(a==0&&b==0) return -1;//无最大公约数
if(b==0){x=1;y=0;return a;}
long long d=extend_gcd(b,a%b,y,x);//要记住这里的y和x换了顺序
y-=a/b*x;//要记住是a在上面,b在下面
return d;//d=gcd(a,b);也就是a,b最小公约数
}  

你可能感兴趣的:(中国剩余定理的解析及记忆(扩展欧几里得算法的运用))