문제
- 링크: https://www.acmicpc.net/problem/16670
- 요약: 기사들은 도착 시각
t와 소요 시간d를 미리 접수합니다. 접수는 시각 오름차순으로 처리되며, 앞선 방문이 끝나야 다음이 시작됩니다. 접수/취소/질의가 섞여 주어질 때, 공주가 시각t에 도착하면 얼마를 기다리는지 출력합니다. 동일 시각 도착 시 공주는 기사 뒤에 섭니다. - 제한:
1 ≤ q ≤ 3·10^5,1 ≤ t, d ≤ 10^6. 각 시점에 접수된 기사들의 시각은 서로 다릅니다. 취소는 아직 취소되지 않은 과거 접수만 가리킵니다.
입력/출력 예시
| |
접근 개요
핵심 공식: 접수 집합에서 누적 처리량을
\[ W(t) = (P(t) - t) - \min_{u \le t} (P(u) - u) \]P(t) = Σ_{u≤t} d(u)라 두면, 시각t의 대기 시간(백로그)은입니다. 이는 “작업 유입은
P, 처리 속도는 1”인 단위 처리 모델에서의 표준 백로그 공식입니다. 공주는 기사보다 뒤에 서므로t에 도착한 기사도P(t)에 포함됩니다.자료구조 설계: 시간 축을 접수/질의에 등장한 모든
t로 좌표압축하고,F[i] = P(c_i) - c_i를 위한 세그먼트 트리(지연 전파, 구간 가산/구간 최소)G[i]로min_{u≤t}(P(u)-u)후보를 얻기 위한 세그먼트 트리(접두 구간 최소) 를 유지합니다. 접수(+ t d)는 해당 좌표부터 끝까지+d(suffix 가산), 질의는F[pos] - min(0, min G[1..pos]))로 계산합니다. 취소는 동일 연산을 부호 반대로 되돌립니다.
flowchart TB
A[이벤트 스트림 q개] --> B[좌표 압축(모든 t)]
B --> C1[세그트리 F: P(t)-t]
B --> C2[세그트리 G: min_{u≤t}(P(u)-u) 후보]
C1 --> D[질의 시 F(pos)]
C2 --> E[질의 시 minPrefix(pos)]
D --> F[W(t) = F - min(0, minPrefix)]
E --> F
알고리즘 설계
- 좌표압축: 모든
+/?의 시간t를 모아 정렬·중복제거 후 1-index로 매핑합니다. - 세그먼트 트리 갱신
- 접수
(+ t d):pos = idx(t)F:[pos..M] += dG:[pos..M] += d후, 같은 시각에서의 “도착 직전” 값을 반영하려G[pos] -= d
- 취소
(- i): 위 연산을 그대로 반대로 적용
- 접수
- 질의
( ? t ):pos = idx(t)Fpos = min(F[pos..pos])가 곧P(t)-tminG = min(G[1..pos]), 여유구간(초기 공백 시간) 허용을 위해min(0, minG)와 비교- 결과
W(t) = Fpos - min(0, minG)
정당성(요지)
- 단위 처리율 모델에서 백로그는 과거 임의 시점
u부터 현재까지 “유입량 − 처리량”의 최대 누적이며, 이는(P(t)-t) - min_{u≤t}(P(u)-u)로 정리됩니다. 접수는 시각 순으로만 진행되고 공주는 같은 시각 기사 뒤에 서므로,P정의와 공식이 정확히 문제 가정을 반영합니다.
복잡도
- 시간: 접수/취소/질의 각각
O(log M)(M=고유 시간 수,M ≤ 2q) - 공간:
O(M)
구현 (C++)
| |
코너 케이스 체크리스트
- 접수 없음 상태에서의 질의:
W(t)=0이어야 하며,min(0, minG)처리로 보장 - 동일 시각 중복 접수 금지 조건 반영: 입력 보장, 자료구조는 좌표 단위 단일 점만 가감
- 취소는 반드시 유효한 과거 접수만: 역연산으로 정확히 되돌림
- 매우 큰
q(3e5):O(log M)연산, 빠른 입출력 사용 - 시간 경계
t=1/1e6: 좌표압축으로 안전
제출 전 점검
- 입출력 버퍼링(
sync_with_stdio(false),tie(nullptr)) 적용 여부 - 세그먼트 트리 범위/인덱스(1-index) 일관성
- 64-bit 정수 사용: 누적 합과 결과는
long long - 취소 처리 시 중복 취소/잘못된 인덱스는 입력상 없음(문제 보장)
참고자료
- 큐잉에서의 백로그 표준 정식:
W(t) = (P(t)-t) - min_{u≤t}(P(u)-u) - 세그먼트 트리(지연 전파) 개요와 응용
코너 케이스 및 실수 포인트
| 케이스 | 설명 | 처리 방법 |
|---|---|---|
| 최소 입력 | N=1 또는 빈 입력 | 반복문 범위·예외 처리 확인 |
| 오버플로우 | 답이 $2^{31}$ 초과 가능 | long long (C++) 등 사용 |
![Featured image of post [Algorithm] C++ 백준 16670번: King Kog의 접견실 - 세그먼트 트리](/post/algorithm/2025-08-14-boj-16670-king-kog-reception-segment-tree/wordcloud_hu_6cfd818e9105dac.webp)
![[Algorithm] C++/Python 백준 16404번: 주식회사 승범이네 - 서브트리 갱신·점 질의](/post/algorithm/2025-08-14-boj-16404-seungbeom-company-subtree-range-add-point-query-cpp-solution/wordcloud_hu_5b19e90cab766906.webp)
![[Algorithm] C++ 백준 16583번: Boomerangs - DFS 간선 페어링](/post/algorithm/2025-08-14-boj-16583-boomerangs-dfs-edge-pairing-cpp-solution/wordcloud_hu_b9cb38873df77e5b.webp)
![[Algorithm] C++ 백준 16670번: King Kog의 접견실 - 세그먼트 트리](/post/algorithm/2025-08-14-boj-16670-king-kog-reception-segment-tree/wordcloud_hu_5e00c45b66a8c4d9.webp)
![[Algorithm] C++ 백준 16877번: 핌버](/post/algorithm/2025-08-14-boj-16877-pimber-cpp-solution/wordcloud_hu_81f8b844c33a91cf.webp)
![[Algorithm] C++/Python 백준 16901번: XOR MST](/post/algorithm/2025-08-14-boj-16901-xor-mst-cpp-python-solution/wordcloud_hu_132a089e1f4ad5d.webp)
![[Algorithm] C++ 백준 7626번: 직사각형](/post/algorithm/2025-09-16-boj-7626-rectangles-union-area-line-sweep-segment-tree-cpp-solution/wordcloud_hu_7145edb7dccef516.webp)
![[Algorithm] C++ 백준 13537번: 수열과 쿼리 1 - 오프라인 BIT](/post/algorithm/2025-08-14-boj-13537-sequence-and-queries-1-offline-bit-cpp-solution/wordcloud_hu_59b915b7f83417c1.webp)
![[Algorithm] C++ 백준 16977번: 히스토그램에서 가장 큰 직사각형과 쿼리 - PBS+세그트리](/post/algorithm/2025-08-14-boj-16977-histogram-queries-pbs-segtree-cpp-solution/wordcloud_hu_9124e8ea937d2fe3.webp)
![[Algorithm] C++ 백준 5466번: 상인](/post/algorithm/2025-08-14-boj-5466-merchant-cpp-solution/wordcloud_hu_d93c7b916911dbcc.webp)
![[Algorithm] C++ 백준 12876번: 반평면 땅따먹기 2](/post/algorithm/2025-08-14-boj-12876-half-plane-land-2-cpp-solution/wordcloud_hu_32e2053cd4ffc146.webp)