Processing math: 100%
본문 바로가기
알고리즘

중국인의 나머지 정리(Chinese remainder theorem)

by 초특급하품 2019. 10. 18.

중국인의 나머지 정리를 이해하기 위해 기초적인 문제를 차근차근 풀어보자.
아래 문제만 풀 수 있다면 한결 가까워질 것이다.

문제

[아이]
할아버지, 나이가 어떻게 되십니까?

[할아버지]
내 나이는 3으로 나누었을 때 1이 남고,
5로 나누었을 때 3이 남고,
7로 나누었을 때 2가 남는단다.

[아이]
;;

 

 

풀이과정

할아버지의 말씀 3가지를 수식으로 바꿔보면 다음과 같다.

  • x1 (mod 3)
  • x3 (mod 5)
  • x2 (mod 7)

위 세 개를 만족하는 x를 구해보자.

우선 첫 번째 수식 x1 (mod 3)만 놓고 보면 간단하다.
x=3n+1

 

두 번째 수식 x3 (mod 5)을 풀기 위해 위 x를 대입하고 변환해보자.
3n+13 (mod 5)3n2 (mod 5)

 

덧셈, 뺄셈, 곱셈은 modular연산에서 닫혀있기 때문에 양 변에 -1을 취해도 식은 성립한다. 하지만 3n을 풀기 위해 양 변에 나눗셈을 할 수는 없다. 따라서 n을 구하기 위해서는 양 변에 Z5={0,1,2,3,4} 에서 3에 대한 곱셈의 역원을 구해야 한다.

 

그럼 잠시 곱셈의 역원을 구하는 방법에 대해 먼저 알아보자.

 

곱셈의 역원 구하는 방법

1. 전부 해보는 방법 O(N)

 

int modInverse(int a, int m) { 
    for(int i = 1; i < m; i++) {
       if ((a*i) % m == 1) {
          return i; 
       }
    }
}
 

 

2. 페르마 소정리 O(log2N)

 

  • m소수, am의 배수가 아니라면 am11 (mod m)
  • a×am21 (mod m)
  • 이전글 참조
  • 제곱의 성질을 이용하면 더 빠르게 가능
int modInverse(int a, int m) {
      int result = 1;
      for(int i = 0; i < m-2; i++) {
        result = (result * a) % m
      }
      return result;
} 
 
 
3. 확장 유클리드 O(log2N)

 

  • 3n1 (mod 5)
  • 3n=5m+1
  • 3n5m=1 를 만족하는 n과 m을 구하는 방법
// return: <gcd(a, b), n, m>
tuple<int, int, int> xGCD(int a, int b) {
      if (b == 0) {
          return make_tuple(a, 1, 0);
      }
      int g, x, y;
      tie(g, x, y) = xGCD(b, a%b);
      return make_tuple(g, y, x-(a/b)*y);
}

 


 

위와 같이 여러 가지 방법으로 modular 내에서 곱셈의 역원을 구할 수 있다. 그럼 다시 돌아와서 3n2 (mod 5) 를 만족하는 n을 구해보자.

 

Z5={0,1,2,3,4} 에서 3에 대한 곱셈의 역원을 구하면 2가 나온다. 양 변에 2를 곱하면 좌변을 n으로 만들 수 있다.
n4 (mod 5) n=5m+4 x=15m+13

 

이제 마지막 세 번째 수식 x2 (mod 7)x를 대입해보자.
15m+132 (mod 7) 15m3 (mod 7)

 

Z7={0,1,2,3,4,5,6} 에서 15에 대한 곱셈의 역원은 1!!
m3 (mod 7) m=7k+3 x=105k+58

 

이렇게 알맞은 x를 구했고, 처음 식에 대입해보면 올바르다는 것을 알 수 있다.

세 번쯤 반복해보니 이 노가다를 수식으로 정리하면 그것이 중국인의 나머지 정리가 된다.

 

중국인의 나머지 정리

xai(mod mi) 가 주어질 때 x를 정리하면 다음과 같다.
xni=1Mi(M1imod mi)ai(mod M)

M=m1m2m3...mn,Mi=M/mi

'알고리즘' 카테고리의 다른 글

nim game과 grundy number  (1) 2019.10.18
포함과 배제, 그리고 뫼비우스 함수  (0) 2019.10.18
투셋(2-sat)  (0) 2019.10.18
Manacher's Algorithm  (0) 2019.10.17
고속 푸리에 변환(FFT, Fast Fourier Transform)  (1) 2019.10.17

댓글