1117. 剩余定理

单点时限: 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));
	}
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值