题目描述
现有两组数字,每组k个,第一组中的数字分别为:a1,a2,…,ak表示,第二组中的数字分别用b1,b2,…,bk表示。其中第二组中的数字是两两互素的。求最小的非负整数n,满足对于任意的i,n - ai能被bi整除。
输入格式
输入数据的第一行是一个整数k,(1 ≤ k ≤ 10)。接下来有两行,第一行是:a1,a2,…,ak,第二行是b1,b2,…,bk
输出格式
输出所求的整数n。
输入输出样例
输入 #1
3
1 2 3
2 3 5
输出 #1
23
说明/提示
所有数据中,第一组数字的绝对值不超过109(可能为负数),第二组数字均为不超过6000的正整数,且第二组里所有数的乘积不超过1018
每个测试点时限1秒
注意:对于C/C++语言,对64位整型数应声明为long long,如使用scanf, printf函数(以及fscanf, fprintf等),应采用%lld标识符。
解释:很明显可以转换成中国剩余定理的形式,那就直接上模板把
#include<iostream>
#define ll long long
using namespace std;
ll a[20],b[20];
ll x=0,m=1;
void exgcd(ll a,ll b,ll &x,ll &y){
if(b==0){ x=1; y=0; return;}
exgcd(b,a%b,x,y);
int tp=x;
x=y; y=tp-a/b*y;
}
ll mul(ll a,ll b){//快速乘
ll r=0;
while(b){
if(b&1) r=(a+r)%m;
a=(a+a)%m;
b>>=1;
}
return r;
}
int main(){
int n=0;cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++) cin>>b[i];
for(int i=1;i<=n;i++) m*=b[i];
for(int i=1;i<=n;i++){
ll t=0,temp=0;
exgcd(m/b[i],b[i],t,temp);
t=(t%b[i]+b[i])%b[i];
x+=mul(mul(a[i],(m/b[i])),t);x%=m;x+=m;x%=m;
}
cout<<x<<endl;
return 0;
}