中国剩余定理
这是该代码能解决同余方程组间除数不互质的情况:
1 LL exgcd(LL a,LL b,LL&x,LL&y) //省略 2 LL china() 3 { 4 LL m=a[1],ans=b[1],x,y; //a[]是模,b[]是余数 5 for(int i=2;i<=n;i++){ 6 LL c=(b[i]-ans%a[i]+a[i])%a[i]; 7 LL gcd=exgcd(m,a[i],x,y),ag=a[i]/gcd; 8 if(c%gcd!=0) return -1;//考虑等式不成立的情况 9 x=qmod(x,c/gcd,ag); 10 ans+=x*m; 11 m*=ag; 12 ans=(ans%m+m)%m; 13 } 14 return (ans%m+m)%m; 15 }
这是假设除数都互质的情况:
//中国剩余定理模板 typedef long long ll; ll china(ll a[],ll b[],int n)//a[]为除数,b[]为余数 { ll M=1,y,x=0; for(int i=0;i<n;++i) //算出它们累乘的结果 M*=a[i]; for(int i=0;i<n;++i) { ll w=M/a[i]; ll tx=0; int t=exgcd(w,a[i],tx,y); //计算逆元 x=(x+w*(b[i]/t)*x)%M; } return (x+M)%M; }
这是我的代码:
LL china()
{
LL m=a[1],ans=b[1],x,y;
for (int i=2;i<=n;i++){
cerr<<ans<<"\n";
exgcd(m,a[i],x,y);
x=((x*(b[i]-ans)%a[i])+a[i])%a[i];
ans+=x*m;
m*=a[i];
ans=(ans%m+m)%m;
}
return (ans%m+m)%m;
}