문제
풀이
Albert가 팔기로 고른 장난감의 번호를 $s$라 합시다. 이때 Alice는 왼쪽 $[1, s - 1]$을 $(s - 1) / 3$-묶음 할인받고, 오른쪽 $[s + 1, n]$을 $(n - s)/3$-묶음 할인받는 것이 최선입니다.
왼쪽과 오른쪽에서 각각 가장 큰 원소를 뽑아내기 위한 우선순위 큐(최대 힙)와 할인된 원소들을 저장할 트리 집합을 하나씩 만듭니다. 이를 lheap, rheap, ldisc, rdisc라 부르겠습니다. 원소는 항상 (가격, 인덱스) 쌍으로 관리합니다.
초기에 $s = 0$이고 lheap과 ldisc는 비어있으며 rdisc에는 $[1, n]$에서 가장 큰 원소 $(n - 1)/3$개가, rheap에는 나머지가 들어있습니다.
$s$에 $3$을 더할 때 마다 아래를 반복하면서 가격을 구해주면 됩니다.
- $s - 3 \le i \le s$인 $i$가 rdisc에 존재하는 경우
$i$는 더 이상 오른쪽에서 할인받을 수 없으므로 rdisc에서 제거한 뒤 다시 rheap에서 원소를 뽑아 할인받습니다.
이때 rheap에서 뽑은 원소의 인덱스가 $s$보다 작거나 같지는 않은지 검사해야 합니다. - $s - 3 \le i < s$인 $i$가 ldisc의 가장 작은 원소보다 가격이 큰 경우
이때는 ldisc의 가장 작은 원소보다 $i$를 할인받는 것이 이득이므로 ldisc의 가장 작은 원소를 꺼내어 lheap에 넣은 뒤 $i$를 할인받습니다. - $s - 3 \le i < s$인 $i$가 ldisc의 가장 작은 원소보다 가격이 작은 경우
나중에 할인받을 수도 있으므로 lheap에 삽입합니다. - 왼쪽편에 원소 3개가 추가되었으므로 lheap에서 하나를 꺼내어 할인받습니다.
- 오른쪽편에 원소 3개가 제거되었으므로 rdisc에서 가장 작은 원소를 제거합니다.
시간 복잡도는 $\mathcal{O}(Tn\log n)$입니다.
코드
1 | |