输入a,b 第i个方程表示为x ≡ ai(mod bi),求x。
1. 模数互质的情况
LL n,m;
LL ai[N],bi[N];//余数 模数
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,x,y);
LL z=x;
x=y;
y=z-y*(a/b);
return d;
}
LL CRT()
{
LL M=1,d,y,x,re=0;
for(int i=1;i<=n;i++)
M*=bi[i];
for(int i=1;i<=n;i++)
{
LL k=M/bi[i];
d=exgcd(k,bi[i],x,y);
x=(x%bi[i]+bi[i])%bi[i];
re=(re+ai[i]*x*k)%M;
}
return re;
}
2. 模数不互质的情况
LL n,m;
LL ai[N],bi[N];
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,x,y);
LL z=x;
x=y;
y=z-y*(a/b);
return d;
}
LL EXCRT()
{
LL x,y;
LL M=bi[1],ans=ai[1];//数组从 1 读入
for(int i=2; i<=n; i++)
{
LL a=M,b=bi[i],c=(ai[i]-ans%b+b)%b;
LL gcd=exgcd(a,b,x,y),bg=b/gcd;
if(c%gcd!=0)
return -1;//扩展欧几里得判断无解
x=(x*(c/gcd)%bg+bg)%bg;
ans+=x*M;
M*=bg;
//ans=(ans%M+M)%M;
}
return ans;
}
2.1 如果爆longlong(_int 128 Linux环境下能够使用)
typedef __int128 LL;
inline __int128 read()
{
__int128 x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
inline void print(__int128 x)
{
if(x<0)
{
putchar('-');
x=-x;
}
if(x>9)
print(x/10);
putchar(x%10+'0');
}