뤼카 정리(루카스 정리, Lucas' Theorem)는 이항계수 nCr을 소수 p로 나눈 나머지를 구할 때 사용되는 정리이다. 이 정리를 이용하면 n과 r이 클 때에도 이항계수를 빠르게 구할 수 있다. 정리의 내용은 다음과 같다.
nCr=(⌊n/p⌋C⌊r/p⌋)(nmodpCrmodp)modp
만약 n<r인 경우 nCr=0으로 간주한다. 0C0=1이다.
위의 식을 다르게 해석하면, n과 r을 p진법으로 나타냈을 때 i번째 자리의 자리값을 각각 ni,ri라고 하면 nCr을 p로 나눈 나머지는 모든 niCri의 곱을 p로 나눈 나머지와 같다는 의미가 된다. 이 값이 0이 아니기 위해서는 ni<ri인 경우가 한 번도 나오지 않아야 한다.
이 방법을 이용하면 p가 크지 않은 경우 이항계수를 효과적으로 구할 수 있게 된다. p 미만의 수에 대한 팩토리얼 값이 전처리되어 있을 경우 이항계수를 구하는 코드는 다음과 같다. 전처리는 이 글에 나온 대로 하면 된다.
typedef long long LL;
LL f(LL n, LL r, LL p)
{
if(n < r)return 0;
else if(n == r)return 1;
else return f(n / p, r / p, p) * modinv(f[n], f[r] * f[n - r] % p) % p;
}
p가 5000 이하로 작다면 처음부터 2차원 배열에 이항계수를 저장해서 modinv 함수 없이 구현할 수도 있다.
[연습문제]
BOJ 11402. 이항 계수 4 (Platinum V)
더보기
뤼카 정리로 이항계수를 구하는 문제이다. M≤2000이므로 2차원 배열을 이용할 수 있다.
'Algorithm > D. Math & Number Theory' 카테고리의 다른 글
55. Permutation Cycle Decomposition (0) | 2021.06.08 |
---|---|
54. Euler's Totient Function (0) | 2021.06.03 |
52. Chinese Remainder Theorem (0) | 2021.06.03 |
51. Extended Euclidean Algorithm (0) | 2021.06.03 |
50. Pigeonhole Principle (0) | 2021.06.02 |