문제 링크
https://www.acmicpc.net/problem/15506
풀이
우선 정원 하나마다 식물이 최대 한개씩만 들어온다고 생각하고 풀이를 생각해봅시다.
하루에 자라는 높이를 어떻게 처리할 수 있을까요? 추가했던 식물이 자라는 것이 아니라 나중에 추가될 식물의 높이를 줄인다고 생각해 봅시다. 1번 쿼리든 2번 쿼리든 높이를 로 관리한다면 이전에 추가했던 식물의 높이를 수정할 필요 없이 같은 효과를 볼 수 있습니다.
만약 1번 쿼리로만 입력이 들어온다고 하더라도 최대 개의 식물만을 심을 수 있습니다. 즉, 높이가 를 초과한 식물을 하나씩 뽑아내는 방식으로 2번 쿼리를 처리해도 최대 번의 연산으로 처리할 수 있습니다. [max, index]를 원소로 갖는 세그먼트 트리를 이용해구간에 를 초과한 식물이 있을 때까지 그 식물을 뽑아내면 구간에서 max 값을 찾는 데에 이고 2번 쿼리가 아무리 많이 들어온다 해도 뽑을 식물의 개수는 최대 개 이므로 총 시간복잡도는 입니다. 2번 쿼리를 처리하기 위해 세그먼트 트리를 떠올렸다면 3번 쿼리 또한 sum 값을 원소로 갖는 세그먼트 트리를 이용해 구간의 합을 구할 수 있다는 것을 알아낼 수 있습니다. 3번 쿼리의 시간복잡도는 입니다.
여러개의 식물을 관리하기 위해서는 어떻게 해야 할까요?
우리가 정원에서 세그먼트 트리를 하는 데에 필요한 정보는 정원에서의 식물 중 최대 높이 (2번 쿼리)와 정원에 있는 식물의 개수 (3번 쿼리) 입니다. 이 두 값을 효율적으로 관리하기 위해 정원을 뜯하는 세그먼트 트리의 리프노드마다 식물을 우선순위 큐로 관리한다면 식물 중 최대 높이와 정원에 있는 식물의 개수를 알아낼 수 있습니다. 이 방식으로는 식물 추가 횟수 최대 번, 최대 높이의 식물 제거 횟수 최대 번으로 우선순위 큐에서 사용하는 총 시간복잡도는 입니다.
문제를 푸는 데에 사용한 가장 큰 시간복잡도는 으로 시간 내에 들어올 수 있습니다.
전체 코드
1 |
|