문제 링크
- http://icpc.me/19651
사용 알고리즘
- 세그먼트 트리
시간복잡도
- $O(Q \log N)$
풀이
2번 쿼리를 푸는 방법을 먼저 알아봅시다.
연속한 세 원소 $A_{i-1}, A_i, A_{i+1}$이 등차수열을 이룬다면 $2A_i = A_{i-1}+A_{i+1}$이 성립합니다.
새로운 수열 $B_i = A_{i-1}+A_{i+1}-2A_i$를 정의하면, 수열 $B$에서 연속된 0의 개수를 구하는 문제로 바뀌게 됩니다.
만약 쿼리로 주어지는 구간의 크기가 2라면 쿼리의 결과는 2가 되고, 2보다 큰 경우에는 (연속한 0의 개수 + 2)가 됩니다. 연속한 0의 개수는 흔히 금광 세그라고 불리는 테크닉을 이용해 $O(\log N)$만에 구할 수 있습니다. 이 부분의 구현은 아래 코드의 11-37번 라인을 참고하시면 됩니다.
1번 쿼리는 수열 $A$의 특정 구간에 등차 수열을 더하는 쿼리입니다.
구간 $[s, e]$에 초항이 $x$, 공차가 $y$인 등차 수열을 더하는 것은 아래에 나와있는 방법을 Fenwick Tree 등을 통해 구현하면 $O(\log N)$만에 처리할 수 있습니다.
- 구간 $[s, e]$의 각 원소에 $x-sy$를 더한다.
- $i \in [s, e]$인 $i$에 대해, $i$번째 원소에 $iy$를 더한다.
수열 $A$의 구간 $[s, e]$에 등차 수열을 더했을 때 수열 $B$에서 값이 변하는 원소는 최대 4개밖에 없습니다. ($s-1, s, e, e+1$)
수열 $A$의 값을 모두 알기 때문에 4개의 지점에 대해서만 세그먼트 트리를 업데이트해주면 문제를 풀 수 있습니다.
전체 코드
1 |
|