CRT - Chinese Remainder Theorem
정의
$m_1,m_2,\cdots,m_n$가 쌍마다 서로소, 즉 $\gcd(m_i,m_j)=1,(i\neq j)$이면, 다음 연립 합동식
\[x\equiv a_1\ (mod\ m_1)\\ x\equiv a_2\ (mod\ m_2)\\ \vdots\\ x\equiv a_n\ (mod\ m_n)\]은 법 $m_1,m_2,\cdots,m_n$에 대해 유일한 해를 가진다.
증명
먼저 해의 존재성에 대해서 증명해보자.
$m=m_1m_2\cdots m_k,\ n_k=\cfrac{m}{m_k}$라고 하자. 이때, $\gcd(n_k,m_k)=1$이므로 베주 항등식 $s_kn_k+t_km_k=1$을 만족시키는 $s_k,t_k$가 존재한다. 이를 합동식의 형태로 고치면 $s_kn_k\equiv 1\ (mod\ m_k)$가 된다.
이때, $x=a_1n_1s_1+a_2n_2s_2+\cdots+a_nn_ns_n\ (mod\ m)$라고 하자. $j\neq k$일때 $m_k\vert\ n_j$임은 자명하고, 이에 의해 $x\equiv a_kn_ks_k\equiv a_k\ (mod\ m_k)$이다. 즉, $x$는 연립합동식의 해가 된다.
자, 그러면 유일성에 대해서 증명해보자.
만약 $x,y$가 연립합동식의 해라고 해보자. 그러면
\[x\equiv a_1\ (mod\ m_1)\quad y\equiv a_1\ (mod\ m_1)\\ x\equiv a_2\ (mod\ m_2)\quad y\equiv a_2\ (mod\ m_2)\\ \vdots\\ x\equiv a_n\ (mod\ m_n)\quad y\equiv a_n\ (mod\ m_n)\\\]이 성립한다. 이때 임의의 $k$에 대해 $x\equiv a_k\equiv y\ (mod\ m_k)$이고, $x-y\equiv0\ (mod\ m_k)$이다.
즉, $x-y$는 모든 $m_k$들의 배수이므로
\[lcm(m_1,m_2,\cdots,m_n)|\ (x-y)\]이고, 이때 $m$들이 쌍마다 서로소이므로 다음이 성립한다.
\[m_1m_2\cdots m_k|(x-y)\]즉, $x\equiv y\ (mod\ m_1m_2\cdots m_n)$이고, 연립합동식의 해가 유일함은 증명되었다.
\[x=a_1n_1s_1+\cdots+a_ns_nm_n\]Coprime?
만약, $m$들이 서로소가 아닌 경우애는 어떻게 해야할까?
이 경우에도 해는 충분히 존재 할 수 있다.
\[x\equiv a_1\ (mod\ m_1)\\ x\equiv a_2\ (mod\ m_2)\]이때, $x=m_1k_1+a_1$이라 할 수 있고, 두 번째 식에 대입하면 $m_1k_1\equiv a_2-a_1\ (mod\ m_2)$이되고, 정리하면
\[m_1k_1+m_2k_2=a_2-a_1\]이 된다. 이제 확장 유클리드법으로 $k_1$을 구할 수 있고, 구한 해를 $k_0$이라 하면 정수 $k$에 대해 $k_1=k_0+k\cfrac{m_2}{g}$가 성립한다. 따라서 $x=m_1k_0+k\cfrac{m_1m_2}{g}+a_1$이고, $\cfrac{m_1m_2}{g}=\text{lcm}(m_1,m_2)$이므로
\[x\equiv m_1k_0+a_1\ (mod\ \text{lcm}(m_1,m_2))\]로 합칠 수 있다.
구현
앞서 과정에서 알아본 것처럼 주어진 $a,m$들에 대해 식들을 확장 유클리드법을 활용하여 차례대로 합쳐나가면 된다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
typedef long long ll;
tuple<ll,ll,ll> eGCD(ll a, ll b)
{
if(!b) return {a,1,0};
auto [g,x,y]=eGCD(b,a%b);
return {g,y,x-a/b * y};
}
pair<ll,ll> com(ll a1, ll m1, ll a2, ll m2)
{
auto [g,k0,_]=eGCD(m1,m2);
ll m = m1/g * m2;
if((a2-a1)%g) return {-1,1};
ll mul = (a2-a1)/g;
k0=k0*mul%m2;
return {(k0*m1+a1)%m,m}
}
pair<ll,ll> crt(vector<ll>&a,vector<ll>&m)
{
ll ra=a[0], rm=m[0];
for(int i=1;i<m.size();i++)
{
auto [a,m]=com(ra,rm,a[i],m[i]);
if(!~m) return {-1,1};
else tie(ra,rm)=tie(a,m);
}
return {ra,rm};
}
참고 문헌
- KMO 바이블 정수론
- https://rkm0959.tistory.com/180
- https://cp-algorithms.com/algebra/chinese-remainder-theorem.html
- https://casterian.net/algo/crt.html
- https://math.stackexchange.com/questions/3761920/if-the-lcm-is-simply-the-product-then-the-integers-are-pairwise-prime