卧薪尝胆,厚积薄发。
扩展中国剩余定理
Date: Sun Jul 01 10:26:01 CST 2018 In Category: 总结
求解不互质的同余模方程组。
已知:
$$ x\equiv a_1(mod\ n_1) $ $
$$ x\equiv a_2(mod\ n_2)$ $
$$\vdots$ $
$$x\equiv a_k(mod\ n_k) $ $
$x=a_1+k_1n_1$ $x=a_2+k_2n_2$
$a_1+k_1n_1=a_2+k_2n_2$
$k_1n_1-k_2n_2=a_2-a_1$
用扩展欧几里得求出方程的解 $k1,k2​$ 。
也就得出了一个满足前两个方程的 $x$ 。
用 $x$ 模 $lcm(n_1,n_2)$ 求得 $a$ ,就得到了合并之后的方程 $x\equiv a(mod\ lcm(n_1,n_2))$

#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
using namespace std;
long long t;
long long n;
long long a[8],m[8];
long long c;
long long res;
long long gcd(long long a,long long b){return b==0?a:gcd(b,a%b);}
long long lcm(long long a,long long b)
{
return a/gcd(a,b)*b;
}
long long exgcd(long long a,long long b,long long &x,long long &y)
{
if(b==0)
{
x=1;
y=0;
return a;
}
long long x1,y1;
long long w=exgcd(b,a%b,x1,y1);
x=y1;
y=x1-a/b*y1;
return w;
}
void china()
{
long long lcmi=m[1];
for(long long i=2;i<=n;i++)
{
long long x,y;
long long t=exgcd(m[i-1],m[i],x,y);
long long w=a[i-1]+x*m[i-1]*(a[i]-a[i-1])/t;
if((a[i]-a[i-1])%t){printf("Case %d: -1\n",c);return;}
lcmi=lcm(m[i],m[i-1]);
while(w<0)w+=lcmi;
while(w>lcmi)w-=lcmi;
m[i]=lcmi;
a[i]=w;
}
res=(a[n]%lcmi+lcmi)%lcmi;
if(res==0)res+=lcmi;
printf("Case %d: %d\n",c,res);
return;
}
int main()
{
cin>>t;
for(c=1;c<=t;c++)
{
scanf("%d",&n);
for(long long i=1;i<=n;i++)
scanf("%d",&m[i]);
for(long long i=1;i<=n;i++)
scanf("%d",&a[i]);
china();
res=0;
}
return 0;
}
In tag:
Copyright © 2020 wjh15101051
ღゝ◡╹)ノ♡