http://www.cnblogs.com/keam37/ keam所有 转载请注明出处
一、中国剩余问题:
对方程组
x≡ai(mod ni) i=1,2,3……
求解x的问题。
结合拓展欧几里得算法我们可以知道
对于一个同余方程
x≡a(mod n)等价于 x+ny=a
利用拓展欧几里得算法可以将其解出
对于方程组很容易想到求 解的交集 的方法
对于两个方程
x≡a1 (mod m1);
x≡a2 (mod m2);
令 x=m1*k+a1……①
则有 m1*k+a1≡a2 (mod m2);
可以得到 k*m1≡(a2-a1) (mod m2)
可以用欧几里得算法求出k0=x0*((a2-a1)/gcd(m1,m2)) mod m2;
k=k0+i*(m2/gcd(m1,m2));i=0,1,2……(注意 这里要使k有解 必满足 gcd(m1,m2)|(a2-a1))
有k≡k0 (mod m2/gcd(m1,m2))
即k=(m2/gcd(m1,m2))*t+k0;代入式①
有x=[m1,m2]*t+m1*k0+a1;([m1,m2]为m1 和 m2 的最小公倍数)
则可重新构造同余方程
x≡(m1*k0+a1) (mod [m1,m2])
再用新的方程联立下一个 最后得到的(m1*k0+a1)即为方程组的解。
代码
1 __int64 exgcd(__int64 a,__int64 b,__int64 &x,__int64 &y)//拓展欧几里得,返回gcd(a,b) 2 { 3 __int64 r; 4 if(b==0) 5 { 6 x=1;y=0; 7 return a; 8 } 9 r=exgcd(b,a%b,x,y); 10 __int64 t=x; 11 x=y; 12 y=t-a/b*y; 13 return r; 14 } 15 __int64 build(__int64 &x1,__int64 &y1,__int64 x2,__int64 y2) 16 { 17 __int64 k,x,y,d; 18 d=exgcd(y1,y2,x,y); 19 if((x2-x1)%d) return -1; 20 k=(x*(x2-x1)/d)%y2; 21 if(k<0) k+=y2; 22 __int64 lcd; 23 if(y1%y2 && y2%y1) lcd=y1*y2/d; 24 else lcd=y1>y2?y1:y2; //lcd为y1,y2的最小公倍数 25 x1=(y1*k+x1)%lcd;y1=lcd; 26 return x1; 27 }
下面讨论的是中国剩余定理更多的应用:
二、利用中国剩余定理的计算机算术运算(待完善)
参考书目:《算法导论》、《初等数论及其应用》