BOJ 10121 - Salad Bar

image.png

스택을 잘 이해해야 풀 수 있는 문제이다.

풀땐 세그먼트 트리도 같이 썼는데, 스택만 써서 O(N)O(N)풀이를 한 번 고안해보도록 하자.


aia_isi=ps_i=p 라면 11이고 아니라면 1-1을 한 것의 현재까지의 합이라고 하자.

그리고 bib_i ii에서 왼쪽에 있는 정답 구간 (bi,i](b_i, i] 라고 하자. 즉, ii에서의 정답은 ibii-b_i 이다.

이건 그걸 사진으로 나타낸 것이다.

image.png

https://www.youtube.com/watch?v=iOjJq_M47rU&ab_channel=OlimpiadaInformatyczna

int cur = 1e9;  
int idx = 0;  
int ans = 0;  
for (int i = 0; i <= n; i++) {  
   while (sz(v) && a[v.back().fi] > a[i])  // 1
      v.pop_back();  
   int idx = i;  
   while (sz(v) && v.back().se <= a[i]) {  // 2
      idx = v.back().first;  
      v.pop_back();  
   }  
   ans = max(ans, i - idx);  
   v.push_back(make_pair(idx, a[i]));  
}

스택에 (bi,ai)(b_i, a_i) 를 관리하는데, abia_{b_i}는 비감소하고 aia_i는 단조감소하게 관리하자.

bjjib_j \cdots j \cdots i가 있을 때, (bj,j)(b_j, j) 구간은 정답으로 가능하므로 [j,i][j, i] 만 정답으로 가능하면 (bj,i](b_j, i] 도 가능하다.

따라서 22처럼 가능한 정답 (bj,j)(b_j, j)가 있다면 bibjb_i \coloneqq b_j 를 해주고 (bj,i)(b_j, i) 처럼 정답을 확장시키면서 계속 pop 한다.

ajaia_j \le a_i 라는 것은 jij \leftarrow i로 이동할 수 있다는 뜻이다.

그리고 11에서는 bjib_j \to i 로 이동할 수 없는 것들을 모두 삭제한다.

11에서 pop을 해도 되는 이유는 어차피 이후에 볼 ii' 들은 i<ii < i' 라서 bjib_j \to i가 안되면 bjib_j \to i'도 안되기 때문이다.

따라서 이렇게 갱신하면 bjib_j \to iibji \to b_j 가 가능해지기 때문에 이 구간을 정답이라고 볼 수 있다.

Tags:

Categories:

Updated:

Comments