中国剩余定理是用来解决同余方程组的问题。如 pku1006:Biorhythms 题
设m1,m2....mk两两互质,
x=a1(mod m1);
x=a2(mod m2);
.
.
x=ak(mod mk);
该方程组在0<=x<M=m1m2...mk有唯一解;
该问题的求解用到了求最大公约数的算法。
求最大公约数的欧几里德算法:
int gcd(int a,int b)//a>=b
{
if(b==0)return a;
else return gcd(b,a%b);
}
如果a,b有最大公约数d,则一定存在整数x,y满足ax+by=d;设d`为b,a%b的最大公约数;
d=ax+by;
d`=bx`+(a%b)y`;
a%b=a-(a/b)*b;
所以:d=d`=bx`+(a-(a/b)*b)y`=ay`+b(x`-(a/b)y`);
所以:x=y`;y =x`-(a/b)y`;
扩展的欧几里德算法能够在求出公约数的同时,也求出满足ax+by=d的x,y值;算法如下:
int x,y;
int Extented_Euclid(int a,int b)//a>b
{
if(b==0){x=1;y=0;return a;}
int d=Extented_Euclid(b,a%b);
int t=x;
x=y;
y=t-(a/b)*y;
return d;
}
中国剩余定理:
x=a1(mod m1);
x=a2(mod m2);
.
.
x=ak(mod mk);
M=m1*m2.....*mk; Mi=M/mi;
因为mi之间相互互质,所以Mi与mi互质,gcd(Mi,mi)=1;存在Mi*pi+mi*qi=1,即Mi*pi=1(mod mi);令ei=Mi*pi,则
ei=0(mod mj)j!=i;
ei=1(mod mj) j=i;
所以,e1*a1+e2*a2+....+ek*ak就是方程组的一个解;
如:
x=1(mod 3);
x=2(mod 5);
x=3(mod 7);
5*7*p1=1(mod 3);-->p1=2;
3*7*p2=2(mod 5);-->p2=2;
3*5*p3=3(mod 7);-->p3=3;
所以:35*2+21*2+15*3=70+42+45=157就是方程的一个解。157%(3×5×7)=52就是方程的0<=x<105唯一的解
剩余定理的算法如下:
int shengyudingli()
{
设m1,m2....mk两两互质,
x=a1(mod m1);
x=a2(mod m2);
.
.
x=ak(mod mk);
该方程组在0<=x<M=m1m2...mk有唯一解;
该问题的求解用到了求最大公约数的算法。
求最大公约数的欧几里德算法:
int gcd(int a,int b)//a>=b
{
if(b==0)return a;
else return gcd(b,a%b);
}
如果a,b有最大公约数d,则一定存在整数x,y满足ax+by=d;设d`为b,a%b的最大公约数;
d=ax+by;
d`=bx`+(a%b)y`;
a%b=a-(a/b)*b;
所以:d=d`=bx`+(a-(a/b)*b)y`=ay`+b(x`-(a/b)y`);
所以:x=y`;y =x`-(a/b)y`;
扩展的欧几里德算法能够在求出公约数的同时,也求出满足ax+by=d的x,y值;算法如下:
int x,y;
int Extented_Euclid(int a,int b)//a>b
{
if(b==0){x=1;y=0;return a;}
int d=Extented_Euclid(b,a%b);
int t=x;
x=y;
y=t-(a/b)*y;
return d;
}
中国剩余定理:
x=a1(mod m1);
x=a2(mod m2);
.
.
x=ak(mod mk);
M=m1*m2.....*mk; Mi=M/mi;
因为mi之间相互互质,所以Mi与mi互质,gcd(Mi,mi)=1;存在Mi*pi+mi*qi=1,即Mi*pi=1(mod mi);令ei=Mi*pi,则
ei=0(mod mj)j!=i;
ei=1(mod mj) j=i;
所以,e1*a1+e2*a2+....+ek*ak就是方程组的一个解;
如:
x=1(mod 3);
x=2(mod 5);
x=3(mod 7);
5*7*p1=1(mod 3);-->p1=2;
3*7*p2=2(mod 5);-->p2=2;
3*5*p3=3(mod 7);-->p3=3;
所以:35*2+21*2+15*3=70+42+45=157就是方程的一个解。157%(3×5×7)=52就是方程的0<=x<105唯一的解
剩余定理的算法如下:
int shengyudingli()
{
int i,ans=0;
for(i=0;i<k;i++)
{
extent_gcd(Mi,mi);
ans=(ans+Mi*x*ai)%M;
}
if(ans<=0)ans+=M;
return ans;
}