x ≡ a [ 1 ] ( m o d m [ 1 ] ) x ≡ a[1] (mod\ \ m[1]) x≡a[1](mod m[1])
x ≡ a [ 2 ] ( m o d m [ 2 ] ) x ≡ a[2] (mod\ \ m[2]) x≡a[2](mod m[2])
x ≡ a [ 3 ] ( m o d m [ 3 ] ) x ≡ a[3] (mod\ \ m[3]) x≡a[3](mod m[3])
. . . ... ...
x ≡ a [ n ] ( m o d m [ n ] ) x ≡ a[n] (mod\ \ m[n]) x≡a[n](mod m[n])
求x
中国剩余定理 CRT
适用于模数为质数的情况
/*
x ≡ a[1] (mod m[1])
x ≡ a[2] (mod m[2])
x ≡ a[3] (mod m[3])
...
x ≡ a[n] (mod m[n])
*/
const int maxn = 1e5+5;
int a[maxn], m[maxn], n;
int crt()
{
int M = 1;
for(int i=1;;i<=n;++i) M *= m[i]; //求M
int Mi ,ans = 0, x = 0, y = 0;
for(int i=1;i<=n;++i)
{
Mi = M / m[i];
exgcd(Mi, m[i], x, y);
ans = (ans + Mi * a[i] * x) % M;
}
return ans;
}
扩展中国剩余定理 EXCRT
适用于模数不为质数的情况 (通用)
const int maxn = 1e5+5;
typedef long long ll;
ll a[maxn], m[maxn];
int n;
ll ksc(ll a, ll b,ll p) //快速乘
{
ll ans = 0;
while(b)
{
if(b & 1) ans = (ans + a) % p;
b >>= 1;
a = (a + a) % p;
}
return ans;
}
ll exgcd(ll a,ll b, ll& x,ll& y)
{
if(b == 0)
{
x = 1;y = 0;
return a;
}
ll r = exgcd(b, a % b, y ,x);
y -= a / b * x;
return r;
}
ll excrt()
{
ll M = m[1];
ll ans = a[1];
ll x = 0,y = 0;
for(int i=2;i<=n;++i)
{
ll d = exgcd(M,m[i],x,y);
if((a[i] - ans) % d) return -1; //无解
// x = (a[i] - ans) / d * x % (m[i] / d);
// 优化
ll c = ((a[i] - ans) % m[i] + m[i]) % m[i]; //保证正数
x = ksc(x,c/d,m[i]/d); //使用快速乘, 防溢出
ans += M * x;
M = M / d * m[i];
ans = (ans % M + M) % M;
}
return (ans % M + M) % M;
}