洛咕
题意:有两组数字,每组k个,第一组中的数字分别为a1,a2,...,ak,第二组中的数字分别为b1,b2,...,bk.其中第二组中的数字两两互素.求最小的非负整数n,满足对于任意的i,n-ai能被bi整除.
分析:看懂题目之后,就是裸的中国剩余定理.
n-ai能被bi整除,即(n-a_i≡0(mod b_i)),移项得(n≡a_i(mod b_i)),然后有k个这样的方程构成方程组,且bi两两互质.裸题证毕.
几个细节:ai可能为负数,稍微处理一下.然后出题人很毒瘤,最后相乘的时候会爆long long,所以要用快速乘(会快速幂就会快速乘).
#include<bits/stdc++.h>
#define LL long long
using namespace std;
inline LL read(){
LL s=0,w=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){s=s*10+ch-'0';ch=getchar();}
return s*w;
}
LL k,M=1,ans;
LL a[11],b[11];
LL quickmul(LL a,LL b,LL mod){
LL ans=0;
while(b){
if(b&1)ans=(ans+a)%mod;
a=(a+a)%mod;
b>>=1;
}
return ans;
}//快速乘:快速幂的乘号变加号
LL exgcd(LL a,LL b,LL &x,LL &y){
if(b==0){x=1;y=0;return a;}
LL d=exgcd(b,a%b,y,x);
y-=x*(a/b);
return d;
}
void Intchina(){
LL Mi,x,y;
for(int i=1;i<=k;++i){
Mi=M/b[i];
exgcd(Mi,b[i],x,y);
x=(x%b[i]+b[i])%b[i];
ans=(ans+quickmul(quickmul(Mi,x,M),a[i],M))%M;
}
printf("%lld
",(ans+M)%M);
}
int main(){
k=read();
for(int i=1;i<=k;i++){
a[i]=read();
}
for(int i=1;i<=k;i++){
b[i]=read();M*=b[i];
while(a[i]<0)a[i]+=b[i];//处理一下ai
}
Intchina();
return 0;
}