BOJ 17975 - Strike Zone

image.png

금광세그로 날먹할 수 있긴한데, x,yx, y가 모두 달라서 더 쉬운 방법(?)으로 풀 수 있기 때문에 그 방법을 설명한다.

동일하게 Segment Tree + Sweeping인데, 금광처럼 Node의 Merge연산을 기발하게 가져가야하는건 아니다.

SolutionPermalink

22차원 평면에서 파란점의 위치엔 c1c_1을 표시해주고 빨간점의 위치엔 c2-c_2 를 모두 표시해준다고 해보자.

그럼 이 문제는 22차원 평면에서 구간의 합이 가장 큰 직사각형을 찾는 문제로 치환된다.

직사각형의 넓이가 00이여도 상관없다. 그냥 22차원의 어떤 영역이라고 생각하자.

일단 모든 점을 좌표압축을 해주고 xx좌표의 개수가 XX, yy좌표의 개수가 YY라고 하자.

정답이 되는 어떤 직사각형은 항상 왼쪽 모서리에 파란 점을 포함한다.

그 점을 p0(y0,x0)p_0(y_0, x_0) 이라고 한다.

dpu,i  (x0i<X)dp_{u,i}~~(x_0 \le i < X)[y0,x0]×[,i][y_0, x_0] \times [\infty, i] 영역에서 값이 최대인 직사각형이라고 해보자.

최대값을 관리하는 Lazy Segment Tree를 이용하면 ii 를 방문했을 때, [yi,)[y_i, \infty) 구간에 그 점이 파란색이라면 c1c_1을, 빨간색이라면 c2-c_2를 더해준다.

그 점을 포함하는 직사각형이 되려면 높이가 최소 yiy_i 가 되야하기 때문이다.

그럼 이제 dpu,i=dp_{u,i}= [yi,)[y_i, \infty) 구간에서의 최대값이므로 트리에 쿼리를 날리면 된다.

이처럼 dpd,idp_{d, i}도 구해준다. dpd,idp_{d, i} 는 위 직사각형이 아닌 아래 직사각형이다.

그럼 p0p_0 를 왼쪽 모서리로 가지는 직사각형중 가장 큰 값은

Maxx0i<X{dpu,i+dpd,ic0}Max_{x_0 \le i < X} \{dp_{u,i}+dp_{d,i}-c_0\} 이다.

c0=c_0=p0p_0의 값

이는 시간복잡도 O(N2logN)O(N^2\log N)에 구현된다.

Tags:

Categories:

Updated:

Comments