单点时限: 2.0 sec
内存限制: 256 MB
求正整数中满足:X mod a[0] = b[0], X mod a[1] = b[1], X mod a[2] = b[2], …, X mod a[i] = b[i], … 的最小解。a[i] 是一些两两互质的正整数。
输入格式
输入数据的第一行为一个正整数 T,表示有 T 组测试数据。
每组测试数据的第一行为一个正整数 M,表示数组 a 和 b 中各有 M 个元素。0<M<=1000
接下来两行,每行各有 M 个正整数,分别为 a 和 b 中的元素。
输出格式
每组输出占一行,输出满足方程组的最小正解 X.
样例
input
2
2
2 3
0 1
3
3 5 7
2 3 2
output
4
23
中国剩余定理
/*
扩展欧几里得求逆元,也可用费马定理
*/
#include<cstdio>
#define ll long long
//扩展欧几里得算法
void gcd(ll a,ll b,ll &d,ll &x,ll &y) {
if(b==0) {
d=a;
x=1,y=0;
} else {
gcd(b,a%b,d,y,x);
y-=(a/b)*x;
}
}
//中国剩余定理
ll China(int n,ll *m,ll *a) {
ll M=1,d,y,x=0;
for(int i=0; i<n; i++) M*=m[i];
for(int i=0; i<n; i++) {
ll w=M/m[i];
gcd(m[i],w,d,d,y);
x=(x+y*w*a[i])%M;
}
return (x+M)%M;
}
ll m[15],a[15];
int main() {
int t;
scanf("%d",&t);
for(int z=0; z<t; z++) {
int n;
scanf("%d",&n);
for(int i=0; i<n; i++)
scanf("%lld",m+i);
for(int i = 0; i < n; i++)
scanf("%lld",a+i);
printf("%lld\n",China(n,m,a));
}
}