문제 분석
BOJ 13925 - 수열과 쿼리 13은 다음 네 가지 쿼리를 효율적으로 처리해야 합니다:
- 쿼리 1: 구간
[x, y]에 모든 원소에v를 더함 (덧셈) - 쿼리 2: 구간
[x, y]에 모든 원소에v를 곱함 (곱셈) - 쿼리 3: 구간
[x, y]의 모든 원소를v로 설정 (값 설정) - 쿼리 4: 구간
[x, y]의 합을 구함 (MOD 10^9+7)
핵심 아이디어
일반적인 Lazy Propagation 세그먼트 트리는 한 종류의 연산만 처리합니다. 이 문제의 핵심은 세 가지 다른 연산을 선형 함수로 통합하는 것입니다.
모든 연산을 다음과 같이 표현할 수 있습니다:
$$f(x) = \text{mul} \cdot x + \text{add}$$- 덧셈 (+v):
mul = 1, add = v→ f(x) = 1·x + v = x + v - 곱셈 (×v):
mul = v, add = 0→ f(x) = v·x + 0 = v·x - 값 설정 (=v):
mul = 0, add = v→ f(x) = 0·x + v = v
Lazy 연산 합성
기존의 미적용 연산 (mul, add)에 새로운 연산 (mul', add')를 적용할 때:
따라서:
new_mul = (mul' × mul) % MODnew_add = (mul' × add + add') % MOD
구현 코드
| |
알고리즘 상세 설명
1. 노드 값 업데이트
연산 (mul, add)를 구간 [l, r]에 적용할 때:
- 크기가
cnt = r - l + 1인 구간의 합:- 기존:
S - 새로운:
S' = (S * mul + add * cnt) % MOD
- 기존:
2. Lazy 값 적용
구간 업데이트 시 자식 노드에 lazy 정보를 전파:
- 자식의 새로운 mul:
child_mul = child_mul * parent_mul - 자식의 새로운 add:
child_add = child_add * parent_mul + parent_add
3. Push Down 과정
쿼리 또는 업데이트 전에 미적용된 lazy 값을 자식에 전파하는 과정입니다.
시간 복잡도 분석
| 작업 | 시간복잡도 |
|---|---|
| 빌드 | O(N) |
| 각 쿼리 | O(log N) |
| 전체 | O((N + M) log N) |
N = 100,000, M = 100,000일 때 약 1,700만 연산으로 충분합니다.
예제 풀이
입력:
| |
실행 과정:
- 초기 배열:
[1, 2, 3, 4] 4 1 4: 구간 [1, 4]의 합 = 1 + 2 + 3 + 4 = 101 1 3 10: 구간 [1, 3]에 10을 더함 →[11, 12, 13, 4]2 2 4 2: 구간 [2, 4]에 2를 곱함 →[11, 24, 26, 8]4 1 4: 구간 [1, 4]의 합 = 11 + 24 + 26 + 8 = 69 (MOD 10^9+7)
출력:
| |
주의사항
- MOD 연산: 모든 계산에서
% MOD를 적용하여 오버플로우 방지 - Lazy 합성 순서:
mul'(mul * x + add) + add'순서 준수 - 구간 크기: 합 계산 시 구간의 원소 개수(
end - start + 1)를 고려해야 함 - 초기 lazy 값:
lazy_mul = 1, lazy_add = 0(항등원)
확장 학습
풀이 팁
이 문제가 어려운 이유는 세 가지 서로 다른 연산을 하나의 프레임워크로 통합해야 한다는 점입니다. 핵심은 모든 연산을 선형 함수로 표현하고, lazy 값을 합성 함수로 처리하는 것입니다. 비슷한 문제로 BOJ 13424, BOJ 14178 등이 있으니 참고하세요.
![Featured image of post [Algorithm] C++ 백준 13925 수열과 쿼리 13](/post/algorithm/2025-12-02-boj-13925-sequence-query-13-segtree-cpp-solution/wordcloud_hu_dd72b7cf75d24789.png)
![[Algorithm] C++ 백준 11869번: 님블](/post/algorithm/2025-12-02-boj-11869-nimble-game-theory-cpp-solution/wordcloud_hu_bf915b4163fb4e18.png)
![[Algorithm] C++ 백준 13310번: 먼 별](/post/algorithm/2025-12-02-boj-13310-distant-star-convex-hull-cpp-solution/wordcloud_hu_a2b702e9b0991507.png)
![[Algorithm] C++ 백준 13925 수열과 쿼리 13](/post/algorithm/2025-12-02-boj-13925-sequence-query-13-segtree-cpp-solution/wordcloud_hu_ff7e3b65400ed471.png)
![[Algorithm] C++ 백준 14504번: 수열과 쿼리 18](/post/algorithm/2025-12-02-boj-14504-sequence-query-18-segtree-cpp-solution/wordcloud_hu_fcca398ee98a773d.png)
![[Algorithm] C++ 백준 15782번: Calculate! 2](/post/algorithm/2025-12-02-boj-15782-calculate-2-tree-segtree-lazy-cpp-solution/wordcloud_hu_c7b151aaf16cbe10.png)
![[Algorithm] C++ 백준 11012번: Egg - 2D 직사각형 쿼리 스위핑+BIT](/post/algorithm/2025-08-14-boj-11012-egg-cpp-solution/wordcloud_hu_ff8aab4a98180994.png)
![[Algorithm] C++ 백준 12858번: Range GCD - 차분+세그트리](/post/algorithm/2025-08-14-boj-12858-range-gcd-cpp-solution/wordcloud_hu_47906873416556e5.png)
![[Algorithm] C++ 백준 13537번: 수열과 쿼리 1 - 오프라인 BIT](/post/algorithm/2025-08-14-boj-13537-sequence-and-queries-1-offline-bit-cpp-solution/wordcloud_hu_cbc1305f194d9d9e.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++ 백준 2261번: 가장 가까운 두 점](/post/algorithm/2025-08-14-boj-2261-closest-pair-of-points-divide-and-conquer/wordcloud_hu_65477ec79671636d.png)