现有两组数字,每组k个,第一组中的数字分别为:a1,a2,...,ak表示,第二组中的数字分别用b1,b2,...,bk表示。其中第二组中的数字是两两互素的。求最小的非负整数n,满足对于任意的i,n - ai能被bi整除。
中国剩余定理,要注意对a[i]为负数时的处理
还要注意快速乘法,因为可能溢出导致答案错误
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> using namespace std; typedef long long ll; ll k,a[17],b[17]; ll exgcd(ll a,ll b,ll &x,ll &y){ if(b==0){ x=1;y=0;return a; } else{ ll d=exgcd(b,a%b,y,x); y-=(a/b)*x; return d; } } ll qmul(ll a,ll b,ll mod){ ll ret=0; for(;b;b>>=1,a=(a+a)%mod){ if(b&1) ret+=a; } return ret; } ll lmes(){ ll tmp=1,m,mf,y,ret=0;; for(ll i=1;i<=k;i++) tmp*=b[i]; for(ll i=1;i<=k;i++){ m=tmp/b[i]; ll k=exgcd(m,b[i],mf,y); mf=(mf%b[i]+b[i])%b[i]; ret=(ret+qmul(qmul(a[i],m,tmp),mf,tmp))%tmp; } return (ret+tmp)%tmp; } int main(){ cin>>k; for(ll i=1;i<=k;i++) cin>>a[i]; for(ll i=1;i<=k;i++) cin>>b[i]; for(ll i=1;i<=k;i++) a[i]=(a[i]%b[i]+b[i])%b[i]; cout<<lmes()<<endl; return 0; }