문제 분석
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 등이 있으니 참고하세요.
코너 케이스 및 실수 포인트
| 케이스 | 설명 | 처리 방법 |
|---|---|---|
| 최소 입력 | N=1 또는 빈 입력 | 반복문 범위·예외 처리 확인 |
| 오버플로우 | 답이 $2^{31}$ 초과 가능 | long long (C++) 등 사용 |
![Featured image of post [Algorithm] C++ 백준 13925 수열과 쿼리 13](/post/algorithm/2025-12-02-boj-13925-sequence-query-13-segtree-cpp-solution/wordcloud_hu_441ba25b483795fd.webp)
![[Algorithm] C++ 백준 11869번: 님블](/post/algorithm/2025-12-02-boj-11869-nimble-game-theory-cpp-solution/wordcloud_hu_a43d6fb95b7f88f8.webp)
![[Algorithm] C++ 백준 13310번: 먼 별](/post/algorithm/2025-12-02-boj-13310-distant-star-convex-hull-cpp-solution/wordcloud_hu_ba34b43eab2b9c01.webp)
![[Algorithm] C++ 백준 13925 수열과 쿼리 13](/post/algorithm/2025-12-02-boj-13925-sequence-query-13-segtree-cpp-solution/wordcloud_hu_dac8fae63ebef02b.webp)
![[Algorithm] C++ 백준 14504번: 수열과 쿼리 18](/post/algorithm/2025-12-02-boj-14504-sequence-query-18-segtree-cpp-solution/wordcloud_hu_3f06a6ae33bc42ba.webp)
![[Algorithm] C++ 백준 15782번: Calculate! 2](/post/algorithm/2025-12-02-boj-15782-calculate-2-tree-segtree-lazy-cpp-solution/wordcloud_hu_e90101ea3a15a18d.webp)
![[Algorithm] C++ 백준 17408번: 수열과 쿼리 24](/post/algorithm/2026-02-23-boj-17408-sequence-and-query-24-segment-tree-cpp-solution/wordcloud_hu_af2d4d2a8fdc290e.webp)
![[Algorithm] C++ 백준 17474번 : 수열과 쿼리](/post/algorithm/2025-08-12-boj-17474-sequence-and-queries-26-cpp-solution/wordcloud_hu_51b1ef37a61e4919.webp)
![[Algorithm] C++ 백준 12844번: XOR](/post/algorithm/2025-12-04-boj-12844-xor/wordcloud_hu_344941b860739c59.webp)
![[Algorithm] C++ 백준 13925번: 수열과 쿼리 13 - Lazy 세그트리](/post/algorithm/2025-08-14-boj-13925-sequence-and-queries-13-cpp-solution/wordcloud_hu_da2baa8b5a419806.webp)
![[Algorithm] C++ 백준 12925번: Numbers](/post/algorithm/2026-01-30-boj-12925-numbers-matrix-exponentiation-cpp-solution/wordcloud_hu_c254298302da6b9f.webp)