https://www.acmicpc.net/problem/1725
import sys
sys.setrecursionlimit(10**5)
N=int(input())
arr=[]
for _ in range(N):
arr.append(int(input()))
tree=[0]*(4*N)
def build_segment_tree(tree,arr,node,start,end):
if start==end:
tree[node]=(arr[start],start)
else:
mid=(start+end)//2
build_segment_tree(tree,arr,node*2,start,mid)
build_segment_tree(tree,arr,node*2+1,mid+1,end)
tree[node]=min(tree[node*2],tree[node*2+1])
def range_query(tree,node,start,end,L,R):
if R<start or L>end:
return (1e9,1e9)
elif L<=start and end<=R:
return tree[node]
else:
mid=(start+end)//2
left_min=range_query(tree,node*2,start,mid,L,R)
right_min=range_query(tree,node*2+1,mid+1,end,L,R)
return min(left_min,right_min)
def getSize(tree,left,right):
minH,minIdx=range_query(tree,1,0,N-1,left,right)
nSize=(right-left+1)*minH
if left<minIdx:
nSize=max(getSize(tree,left,minIdx-1),nSize)
if minIdx<right:
nSize=max(getSize(tree,minIdx+1,right),nSize)
return nSize
build_segment_tree(tree,arr,1,0,N-1)
print(getSize(tree,0,N-1))
히스토그램이 각 높이를 통해 주어졌을 때, 구해질 수 있는 직사각형의 최대 넓이를 구하는 문제이다. 이 때, 높이의 범위가 10억이내이고 밑변의 최대 길이가 100,000이므로 NlogN 정도의 시간복잡도가 걸릴 것이라 예상하였다.
현재의 구간에서의 최대 넓이를 구하는데, 이때 필요한 것은 구간에서의 최소 합이므로 이를 세그먼트 트리를 통하여 logN으로 빠르게 가져올 수 있다. 이렇게 구한 높이를 통하여 현재에서의 넓이를 구해주고 이 최소 높이를 가지는 부분을 기준으로 해서 왼쪽과 오른쪽에서의 최대 넓이도 구한다. 이렇게 분할 정복을 해 들어가면 되는 것이다.
이렇게 Python으로 백준의 "히스토그램" 문제를 해결해보았습니다. 코드와 개념 설명을 참고하여 문제를 해결하는 데 도움이 되셨길 바랍니다! 😊