개념
구간 병합은 여러 구간이 덮는 범위를 겹치지 않는 구간들로 정리하는 방법입니다. 예약된 시간이나 사용 중인 번호 범위를 합칠 때 사용합니다. 구간 선택은 일부 구간을 골라 개수를 최대화하지만, 병합은 모든 구간이 덮는 범위를 보존합니다.
시작점 순서로 확인
시작점이 작은 순서로 정렬하고, 현재 합치고 있는 구간의 양 끝점을 , 로 저장합니다. 다음 구간을 라고 하면 두 경우로 나뉩니다.
| 조건 | 처리 |
|---|---|
| 겹치거나 끝점이 닿으므로 을 로 갱신 | |
| 현재 구간을 결과에 넣고 를 새 구간으로 시작 |
예를 들어 정렬한 구간이 , , , 이면 먼저 를 저장합니다. 은 그 안에 포함되므로 오른쪽 끝점은 입니다. 은 끝점이 닿으므로 으로 합칩니다. 는 떨어져 있으므로 최종 결과는 , 입니다.
떨어진 구간을 확정하는 이유
현재 오른쪽 끝점이 이고 다음 시작점 가 보다 크다면, 뒤의 구간들도 시작점이 이상입니다. 시작점 순서로 정렬했기 때문입니다. 따라서 뒤의 어떤 구간도 현재 구간과 겹칠 수 없으므로 현재 구간을 확정할 수 있습니다.
합칠 때는 오른쪽 끝점을 두 끝점의 최댓값으로 정해야 합니다. 현재 구간 안에 들어가는 짧은 구간을 만났을 때 끝점을 줄이면 이미 덮고 있던 범위가 사라집니다.
복잡도
구간 수를 이라고 합니다.
| 연산 | 시간복잡도 | 공간복잡도 |
|---|---|---|
| 정렬을 포함한 병합 | 입력·결과 저장 | |
| 정렬된 구간 확인 | 결과 저장 |
예제
문제
주어진 구간들 중 겹치거나 끝점이 닿는 구간을 모두 합쳐라.
입력
첫째 줄에 구간 수 이 주어진다. 이다.
다음 개 줄에 구간의 시작점 와 끝점 가 공백을 사이에 두고 주어진다. 이다.
출력
첫째 줄에 병합된 구간 수를 출력한다. 다음 줄부터 각 구간의 시작점과 끝점을 공백을 사이에 두고 한 줄에 출력한다. 구간은 시작점이 작은 순서대로 출력한다.