求解同余式方程组
x≡b1(mod a1) 1
x≡b2(mod a2) 2x≡b3(mod a3) 4
x≡b4(mod a4) 5
.
.
.
求解x模数不互质的情况 两两合并的思想
x=k1*a1+b1≡b2(mod a2)k1*a1≡b2-b1(mod a2)
裴蜀定理:对于方程 a*x+b*y=n;有整数解的充分必要条件是(n % gcd(a,b)== 0),
即n能够被a和b的最大公约数整除,其实就是扩展的欧几里得定理
C=b2-b1; g=gcd(a1,a2);
k1*a1/g=k2*a2/g+C/g;
k1*a1/g≡C/g(mod a2/g) 求k1
令t*a1/g≡=1(mod a2/g) 逆元概念
k1=C/g*t(mod a2/g)
k1=k2*a2/g+C/g*t 代入x=k1*a1+b1=(k2*a2/g+C/g*t)*a1+b1;
x=k2*a2*a1/g+C/g*t*a1+b1;
x≡C/g*t*a1+b1(mod a2*a1/g)≡C/g*t*a1+b1(mod lcm(a1,a2)) 3---->1,2合并生成新的同余式3
然后用新生成的同余式3和4继续做合并,直到结束。x就是所求的解.
ll solve()
{
ll n,m;
scanf("%I64d",&m);
for(int i=0;i<m;i++) scanf("%I64d",&a[i]);///模数
for(int i=0;i<m;i++) {scanf("%I64d",&b[i]);b[i]=(b[i]%a[i]+a[i])%a[i];}///取模结果
bool flag=false;
ll a1,b1,a2,b2;
a1=a[0],b1=b[0];
for(int i=1;i<m;i++)
{
a2=a[i],b2=b[i];
if(flag) continue;
ll x,y,B;
ll g=gcd(a1,a2);
if((B=b2-b1)%g!=0)
{
flag=true;//无解
continue;
}
B/=g;
a2/=g;
a1/=g;
ll G=exgcd(a1,a2,&x,&y);///求逆元
x=x*B/G%a2;
b1=x*a1*g+b1;
a1=a1*a2*g;
b1=(b1%a1+a1)%a1;
}
if(flag) return (ll)-1;
return b1?b1:a1;
}
中国剩余定理:
解决一类a1,a2,a3,a4,...两两互质的问题。
令M=lcm(a1,a2,a3,....)
M/ai*xi≡1(mod ai);逆元
M/ai*xi≡0(mod aj);i!=j
gcd(ai,M/ai)=1
x=M/a1*x1*b1+M/a2*x2*b2+M/a3*x3*b3+...。
有点构造性,但是有证明。
http://www.doc88.com/p-5903949343631.html
long long crt(long long m[],long long a[])
{///m 模数数组 a余数数组
long long i,M=1,res=0,ans;
for(i=0;i<n;i++) M*=m[i];
for(i=0;i<n;i++)
{
long long tm=M/m[i],x,y;
ans=gcd_ex(tm,m[i],&x,&y);
res=(res+tm*a[i]*x)%M;
}
return res;
}