문제 요약
문제 링크: https://www.acmicpc.net/problem/13182
특정 빨간색(R개), 초록색(G개), 파란색(B개) 제비를 통에 넣고 차례로 뽑을 때:
- 빨간 제비: 버림
- 초록 제비: 다시 넣음
- 파란 제비: 다시 넣음 (K번 뽑으면 멈춤)
요구사항: 잠을 자러 갈 때까지 뽑게 될 제비 개수의 기댓값을 (a × b^(-1)) mod 10^9+7로 출력
제한 사항: 1 ≤ R, G, B, K ≤ 10^9, 1 ≤ T ≤ 10^3
입출력 예제
입력 1:
| |
출력 1:
| |
설명: 첫 번째 테스트 케이스는 5/2를 의미합니다.
접근 개요
핵심 관찰
상태를 “남은 빨간 제비 개수"와 “아직 뽑아야 할 파란 제비 개수"로 정의합니다.
E(r, k) = r개의 빨간 제비가 남아있고 k번 더 파란 제비를 뽑아야 할 때의 기댓값
점화식 유도
한 번의 뽑기에서:
- 빨간색 확률: r/(r+g+b) → 1번 뽑고 상태 E(r-1, k)
- 초록색 확률: g/(r+g+b) → 1번 뽑고 상태 E(r, k)
- 파란색 확률: b/(r+g+b) → 1번 뽑고 상태 E(r, k-1)
| |
정리하면:
| |
재귀적으로 풀면:
| |
수식 증명
기저 단계: E(0, k) = k × (G+B) / B
귀납 단계: 위 공식이 E(R, K) = Σ[i=0 to K-1] ((1 - (B/(B+1))^(i+1)) × R/(i+1)) + … 의 기하급수로 표현될 수 있음을 보일 수 있습니다.
알고리즘 설계
수식 계산
- 비율 계산: ratio = B / (B+1) (mod p에서 modular inverse 사용)
- 거듭제곱: ratio^K 계산 (fast exponentiation)
- 첫 항: term1 = R × (1 - ratio^K)
- 두 번째 항: term2 = K × (G+B) / B
- 최종 답: (term1 + term2) mod p
모듈로 연산
- 페르마의 소정리: a^(p-1) ≡ 1 (mod p) ⟹ a^(-1) ≡ a^(p-2) (mod p)
- 거듭제곱 지수: exp mod (p-1) 적용
- 모든 나눗셈은 modular inverse 사용
복잡도
- 시간 복잡도: O(T × log K) - 각 테스트마다 fast exponentiation
- 공간 복잡도: O(1)
구현
| |
코너 케이스 체크리스트
K = 1: 파란 제비를 한 번만 뽑는 경우
- 기댓값 = (R+G+B) / B
R = 0: 빨간 제비가 없는 경우
- 기댓값 = K × (G+B) / B (상수)
G = 0: 초록 제비가 없는 경우
- 기댓값 = R × (1 - (B/(B+1))^K) + K
G = B = 1000000000, K = 10000000: 최대 입력
- 모듈로 연산과 거듭제곱 오버플로우 주의
제출 전 점검 목록
- modular inverse 계산 정확성 (Fermat’s Little Theorem)
- 거듭제곱 지수를 (MOD-1)로 나눔 확인
- 각 변수가 long long 타입 (10^9 초과 가능)
- 음수 mod 처리: (1 - ratio_K + MOD) % MOD
- 모든 곱셈/덧셈에 mod 적용
참고자료
- Fermat’s Little Theorem: 소수 p에 대해 a^(p-1) ≡ 1 (mod p)
- Modular Inverse: a × a^(-1) ≡ 1 (mod p)
- 기하급수: Σ x^i = (1 - x^(n+1)) / (1 - x)
유사 문제
- BOJ 10994: 별 찍기 - 19
- BOJ 13926: gcd(n, k) = 1
- BOJ 1722: 순열의 순서
성공적인 제출을 위한 최종 팁:
- 입력 크기가 10^9이므로 모든 수를 MOD로 정규화
- 거듭제곱에서 지수도 (MOD-1)로 나눔 (Fermat’s little theorem)
- 결과 분수를 (분자 × 분모의 역원) % MOD로 계산
- 음수 mod 결과 처리 시 +MOD 후 mod 연산
![Featured image of post [Algorithm] C++ 백준 13182번 제비](/post/algorithm/2025-12-04-boj-13182-lottery-draw-expectation-cpp-solution/wordcloud_hu_ceea64a7a5bb0d83.png)
![[Algorithm] C++ 백준 13182번 제비](/post/algorithm/2025-12-04-boj-13182-lottery-draw-expectation-cpp-solution/wordcloud_hu_6c18b6c0307518c2.png)
![[Algorithm] C++ 백준 17682번 Tents](/post/algorithm/2025-12-04-boj-17682-tents-combinatorics-cpp-solution/wordcloud_hu_2726d57ba0310c29.png)
![[Algorithm] C++ 백준 16481번 원 전문가 진우 - 방접원과 내접원의 관계](/post/algorithm/2025-12-03-boj-16481-excircle-incircle-geometry-cpp-solution/wordcloud_hu_ee675f3393f22f00.png)
![[Algorithm] C++ 백준 27533번 따로 걸어가기](/post/algorithm/2025-12-03-boj-27533-walk-separately-lindstrom-cpp-solution/wordcloud_hu_bcc1a69354c31bd3.png)
![[Algorithm] C++/Python 백준 12735번: Boat](/post/algorithm/2025-08-14-boj-12735-boat-cpp-python-solution/wordcloud_hu_dfad17dd2b1a530d.png)
![[Algorithm] C++ 백준 14897번: 서로 다른 수와 쿼리 1](/post/algorithm/2025-08-14-boj-14897-distinct-in-range-queries-1-cpp-solution/wordcloud_hu_fcf9b2f0117a9599.png)
![[Algorithm] C++ 백준 15977번: 조화로운 행렬 - 3D LIS/CDQ](/post/algorithm/2025-08-14-boj-15977-harmonious-matrix-cdq-3d-lis-cpp-solution/wordcloud_hu_54a36fa0759d464d.png)
![[Algorithm] C++ 백준 16877번: 핌버](/post/algorithm/2025-08-14-boj-16877-pimber-cpp-solution/wordcloud_hu_90d8ca4b93931bd1.png)