标签:扩展 crt 同余 gcd exgcd ++ 情况 相关 ret
解决同余方程组的相关问题,然而貌似扩展一下发生质变?
\[x\equiv a_1 \mod m_1 \]
\[x\equiv a_2 \mod m_2 \]
\[\dots\dots\]
\[x\equiv a_n \mod m_n \]
求解满足上述同余方程组的\(x\)
const int maxn=1000;
int a[maxn];
int m[maxn];
int CRT(int n){
int M=1;
int ans=0;
for(int i=1;i<=n;i++){
M*=m[i];
}
for(int i=1;i<=n;i++){
int x,y;
int Mi=M/m[i];
exgcd(Mi,m[i],x,y);
ans=(ans+a[i]*Mi*x)%M;
}
if(ans<0)ans+=M;
return ans;
}
const int maxn=1000;
int a[maxn];
int m[maxn];
int gcd(int a,int b){
return b?gcd(b,a%b):a;
}
int exgcd(int a,int b, int &x,int &y){
if(b==0){
x=1;
y=0;
return a;
}
int d=exgcd(b,a%b,x,y);
int tmp=x;
x=y;
y=tmp-a/b*y;
return d;
}
int inv(int a,int mod){
int x,y;
int d=exgcd(a,mod,x,y);
return d==1?(x%mod+mod)%mod:-1;
}
int exCRT(int n){
int m1, m2, c1, c2, d;
for(int i=2;i<=n;i++){
m1=m[i-1];//这里是与前一个进行合并
m2=m[i];
c1=a[i-1];
c2=a[i];
d=gcd(m1,m2);
if((c2-c1)%d!=0){
return -1;//无法合并
}
m[i]=m[i-1]*m[i]/d;//公式(倒数第二个)
a[i]=c1+m1*inv(m1/d,m2/d)%(m2/d)*(c2-c1)/d;//公式(倒数第二个)
a[i]=(a[i]%m[i]+m[i])%m[i];
}
return a[n];
}
标签:扩展 crt 同余 gcd exgcd ++ 情况 相关 ret
原文地址:https://www.cnblogs.com/tongseli/p/11614623.html