https://www.acmicpc.net/problem/14854
14854번: 이항 계수 6
자연수 N과 정수 K가 주어졌을 때 이항 계수 (NK)를 142857으로 나눈 나머지를 구하는 프로그램을 작성하시오.
www.acmicpc.net
nCkmod142857을 빠르게 계산해야하는 문제. 142857=33×11×13×37으로 합성수라는 점에서 난이도가 상승했다.
(풀이)
우선 nCk를 27, 11, 13, 37로 나눈 나머지를 구하고 나면, 중국인의 나머지 정리를 이용해서 본 문제를 해결할 수 있음을 안다.
두 함수를 정의한다. 소수 p와 자연수 x에 대해,
kp(x)=max
으로 정의한다. 즉, r_p(x)와 p는 서로소이다.
k_p(x!)를 계산하는 방법은 굉장히 잘 알려져 있다.
k_p(x!) = \lfloor x / p \rfloor + \lfloor x / p^2 \rfloor + \lfloor x / p^3 \rfloor + \cdots
왜냐하면 1부터 x까지 자연수 중 p를 약수로 가지는 수의 개수는 \lfloor x / p \rfloor, p^2을 약수로 가지는 수의 개수는 \lfloor x / p^2 \rfloor, ... 이기 때문이다.
_n C _k = \frac{n!}{k! (n-k)!} 이기 때문에, k_p(n!) > k_p(k!) + k_p((n-k)!) 이면 _n C _k를 p로 나눈 나머지는 0 이다.
그렇지 않다면 r_p(n!), r_p(k!), r_p((n-k)!)을 p로 나눈 나머지와 모듈러 역 연산을 이용해서 구할 수 있다.
r_p(x!) = r_p(1) \cdot r_p(2) \cdot r_p(3) \cdots r_p(x) 이다.
r_p(x)를 p로 나눈 나머지가 주기성을 가짐을 알면 문제를 어렵지 않게 해결할 수 있다.
\begin{align*} r_p(x!) &\equiv r_p(1) \cdot r_p(2) \cdot r_p(3) \cdots r_p(x) \\ &\equiv \left( r_p(1) \cdot r_p(2) \cdots r_p(p) \right) \left( r_p(p+1) \cdot r_p(p+2) \cdots r_p(2p) \right) \cdots \\ &\equiv \left( r_p(1) \cdot r_p(2) \cdots r_p(p-1) \cdot r_p(p) \right) \left( r_p(1) \cdot r_p(2) \cdots r_p(p-1) \cdot r_p(2p) \right) \cdots \left( r_p((x \:\operatorname{mod}\: p)!) \right) \\ &\equiv r_p(p!)^{\lfloor x / p \rfloor} \cdot r_p(\lfloor x / p \rfloor!) \cdot r_p((x \:\operatorname{mod}\: p)!) \:\operatorname{mod}\: p \end{align*}
윌슨의 정리에 의해 소수 p에 대해, r_p(p!) \:\operatorname{mod}\: p = p - 1 임을 이용하고, x \geq p 인 경우에 한해서는 재귀식으로, x < p 일 때는 직접 계산하는 방식으로 r_p(x!)을 빠르게 구할 수 있다.
문제는 27 = 3^3 으로 나눈 나머지를 구하는 경우이다. 27이 소수가 아니기 때문에 다른 접근이 필요하다. 정확히는 r_3(n!), r_3(k!), r_3((n-k)!)을 27로 나눈 나머지가 필요하다.
r_3(x!)을 27로 나눈 나머지를 구해보자. 1부터 x까지 자연수 중, 3으로 나누어 떨어지는 수와 그렇지 않은 수로 구분해서 생각하면 아래와 같이 식 전개가 가능하다.
\begin{align*} r_3(x!) &\equiv r_3(1) \cdot r_3(2) \cdot r_3(3) \cdots r_3(x) \\ &\equiv \left( r_3(1) \cdot r_3(2) \cdot r_3(4) \cdot r_3(5) \cdots r_3(25) \cdot r_3(26) \right) \cdots \left( r_3(3) \cdot r_3(6) \cdots r_3(3 \cdot \lfloor x / 3 \rfloor) \right) \\ &\equiv \left( r_3(1) \cdot r_3(2) \cdot r_3(4) \cdot r_3(5) \cdots r_3(25) \cdot r_3(26) \right)^{\lfloor x / 27 \rfloor} \cdot r_3(\lfloor x / 3 \rfloor !) \cdot r_3^* (x \:\operatorname{mod}\: 27) \\ &\equiv r_3^*(27)^{\lfloor x / 27 \rfloor} \cdot r_3(\lfloor x / 3 \rfloor !) \cdot r_3^*(x \:\operatorname{mod}\: 27) \:\operatorname{mod}\: 27 \end{align*}
단, r_3^*(x) 는 1부터 x까지 3과 서로소인 모든 자연수의 곱으로 정의한다.
이제 n!, k!, (n-k)!을 각각 27, 11, 13, 37로 나눈 나머지를 안다. 중국인의 나머지 정리를 이용하면 된다.