문제 링크
- http://icpc.me/18944
사용 알고리즘
- 파라메트릭 서치
- 누적합
시간복잡도
- $O(N \log N)$
풀이
구간 $[s, e]$의 Non Decreasing Subarray의 개수를 $C(s, e)$로 정의합시다.
Platina는 $L$ 또는 $R$을 부를 것이고, Yuto는 $\max(C(L, t), C(t, R))$이 최소가 되는 $t$를 부를 것입니다.
$L, R$이 고정되어 있을 때 어떤 지점까지는 $C(L, t) \leq C(t, R)$이고, 그 다음 지점부터는 $C(L, t) < C(t, R)$입니다. $\max(C(L, t), C(t, R))$가 최소가 되기 위해서는 $C(L, t)$와 $C(t, R)$의 대소 관계가 바뀌는 경계를 선택해야 합니다.
만약 $C(s, e)$를 $T(N)$ 시간에 구할 수 있다면 대소 관계가 바뀌는 경계는 파라메트릭 서치를 이용해 $T(N) \log N$에 구할 수 있습니다. $C(s, e)$를 $O(1)$에 구하는 방법을 알아봅시다.
연속한 $X$개의 원소가 감소하지 않는 수열이라면, 그 구간에서의 Non Decreasing Subarray의 개수는 $\frac{X(X+1)}{2}$입니다. 해당 구간의 시작 지점에 $\frac{X(X+1)}{2}$를 더하고 누적합을 구해주면 $O(N)$만에 전처리를 할 수 있습니다.
$C(s, e)$의 값을 구하는 것은 위에서 만든 누적합 배열을 활용해서 $O(1)$만에 구해줄 수 있습니다. 구현이 까다로울 수 있는데, 아래 3가지 경우에 대해 각각 코딩해주면 됩니다.
- 연속한 ‘감소하지 않는 수열’의 오른쪽 일부가 구간 $[s, e]$에 포함되는 경우
- 연속한 ‘감소하지 않는 수열’이 모두 구간 $[s, e]$에 포함되는 경우
- 연속한 ‘감소하지 않는 수열’의 왼쪽 일부가 구간 $[s, e]$에 포함되는 경우
2번째 케이스는 누적합을 이용해 $O(1)$만에 처리할 수 있고, 1, 3번째 케이스는 한 번 밖에 나오지 않기 때문에 적절히 구현해주면 됩니다.
전체 코드
1 |
|