두 사람(Alice, Bob)의 능력치가 길이 \(N\) 배열로 주어지고, 팀 능력치는 \(\sum_{i=1}^{N} \max(A_i, B_i)\)이다.
훈련은 매번 A 전체 또는 B 전체에 같은 값 \(X\)를 더하며, 각 훈련 직후의 팀 능력치를 출력한다.
문제 정보
문제 링크: https://www.acmicpc.net/problem/33543
문제 요약:
- 초기 능력치 \(A_i, B_i\)가 주어진다.
- 쿼리 \(Q\)개가 주어지며, 각 쿼리는
A X또는B X형태로 해당 사람의 모든 능력치에 \(X\)를 더한다. - 각 쿼리 이후 \(\sum_{i=1}^{N} \max(A_i, B_i)\) 값을 출력한다.
제한 조건:
- 시간 제한: 4초
- 메모리 제한: 1024MB
- \(1 \le N \le 250{,}000\)
- \(1 \le Q \le 250{,}000\)
- \(1 \le A_i, B_i, X \le 10^6\)
입출력 예제
입력 1:
| |
출력 1:
| |
접근 방식
핵심 관찰 1: \(\max(A_i, B_i)\)를 “B 기준 + 양수 부분”으로 분해
쿼리 누적을 \(A_i' = A_i + \text{addA}\), \(B_i' = B_i + \text{addB}\)라고 두면
\[ \max(A_i', B_i') = B_i' + \max(A_i' - B_i', 0) \]여기서
\[ d_i = A_i - B_i,\quad \delta = \text{addA} - \text{addB} \]로 두면
\[ A_i' - B_i' = d_i + \delta \]따라서 팀 능력치는
\[ \sum_i \max(A_i', B_i') = \underbrace{\sum_i B_i}_{\text{고정}} + N\cdot \text{addB} + \sum_i \max(d_i + \delta, 0) \]문제는 매 쿼리마다 \(\sum_i \max(d_i + \delta, 0)\)만 빠르게 계산하면 된다.
핵심 관찰 2: \(d\)를 정렬하면, 양수 구간은 suffix 하나로 결정된다
\(d\)를 오름차순 정렬해 두면, 조건 \(d_i + \delta > 0\)는 \(d_i > -\delta\)와 같다.
즉, 임계값 \(-\delta\)를 기준으로 suffix가 양수 구간이 된다.
- \(k = \text{upper\_bound}(d, -\delta)\) (즉, \(d_k > -\delta\)가 시작되는 인덱스)
- \(i \ge k\)에 대해 \(\max(d_i + \delta, 0) = d_i + \delta\)
prefix sum으로 \(d\)의 suffix 합을 즉시 구하면:
\[ F(\delta)=\sum_i \max(d_i+\delta,0) = \sum_{i\ge k} (d_i+\delta) = \left(\sum_{i\ge k} d_i\right) + (N-k)\cdot \delta \]각 쿼리는 upper_bound 한 번으로 \(O(\log N)\)에 처리된다.
알고리즘 설계 (Mermaid Flowchart)
flowchart TD
I["입력: N, (A_i,B_i), Q"] --> P["전처리: sumB=ΣB_i, d_i=A_i-B_i 계산"]
P --> S["d 정렬 + prefix sum 구축"]
S --> L["상태 유지: addB, delta=addA-addB"]
L --> Q{"쿼리: 'A X' 또는 'B X'"} --> U["addB/delta 갱신"]
U --> B["k = upper_bound(d, -delta)"]
B --> F["F = (suffixSum(d,k)) + (N-k)*delta"]
F --> O["ans = sumB + N*addB + F 출력"]
O --> Q
복잡도 분석
| 항목 | 복잡도 | 비고 |
|---|---|---|
| 시간 복잡도 | \(O(N\log N + Q\log N)\) | 정렬 + 각 쿼리 upper_bound |
| 공간 복잡도 | \(O(N)\) | 정렬 배열 + 누적합 |
코너 케이스 및 실수 포인트
| 케이스 | 설명 | 처리 방법 |
|---|---|---|
| delta가 매우 음수/양수 | \(-\delta\) 임계값이 배열 범위 밖 | upper_bound로 \(k=0\) 또는 \(k=N\) 자연 처리 |
| 답 오버플로우 | \(N,Q\)가 25만, 누적 증가가 클 수 있음 | long long 사용 |
| upper_bound 기준 | \(d_i + \delta > 0\) vs \(\ge 0\) 혼동 | d_i > -delta이므로 upper_bound(d, -delta) |
구현 코드
C++
| |
![Featured image of post [Algorithm] C++ 백준 33543번: 둘이 한 팀](/post/algorithm/2025-12-19-boj-33543-two-in-a-team-cpp-solution/wordcloud_hu_57a1947062330537.png)
![[Algorithm] C++ 백준 32115번: 돌 놓기 게임](/post/algorithm/2025-12-19-boj-32115-stone-placing-game-cpp-solution/wordcloud_hu_b5570483586eb270.png)
![[Algorithm] C++ 백준 32190번: Ian Sequences](/post/algorithm/2025-12-19-boj-32190-ian-sequences-cpp-solution/wordcloud_hu_266416599cd1461b.png)
![[Algorithm] C++ 백준 33543번: 둘이 한 팀](/post/algorithm/2025-12-19-boj-33543-two-in-a-team-cpp-solution/wordcloud_hu_791f9bd4be457f3c.png)
![[Algorithm] C++ 백준 3948번: 홍준이의 친위대](/post/algorithm/2025-12-19-boj-3948-hongjuns-royal-guards-cpp-solution/wordcloud_hu_72c9c02c1d626af1.png)
![[Algorithm] C++ 백준 5498번: Batch Scheduling](/post/algorithm/2025-12-19-boj-5498-batch-scheduling-cpp-solution/wordcloud_hu_ea128457d0ff4d1c.png)
![[Algorithm] C++ 백준 22878번: 간단한 문제](/post/algorithm/2025-12-19-boj-22878-simple-problem-cpp-solution/wordcloud_hu_9cd053bc1be8114a.png)
![[Algorithm] C++ 백준 3006번: 터보소트](/post/algorithm/2025-12-19-boj-3006-turbosort-cpp-solution/wordcloud_hu_cd4b400156e60fdb.png)
![[Algorithm] C++ 백준 2586번: 소방차](/post/algorithm/2025-12-19-boj-2586-firetruck-cpp-solution/wordcloud_hu_c7df555f7b0ecd9e.png)
![[Algorithm] C++ 백준 1777번: 순열복원](/post/algorithm/2025-12-19-boj-1777-permutation-recovery-cpp-solution/wordcloud_hu_e783e8b2198c2957.png)
![[Algorithm] C++ 백준 17965번: Absolute Game](/post/algorithm/2025-12-19-boj-17965-absolute-game-cpp-solution/wordcloud_hu_f6800a55fcd520be.png)