https://www.acmicpc.net/problem/2357
2357번: 최솟값과 최댓값
N(1 ≤ N ≤ 100,000)개의 정수들이 있을 때, a번째 정수부터 b번째 정수까지 중에서 제일 작은 정수, 또는 제일 큰 정수를 찾는 것은 어려운 일이 아니다. 하지만 이와 같은 a, b의 쌍이 M(1 ≤ M ≤ 100
www.acmicpc.net
처음에는 list를 잘라서 min, max를 구했는데 시간초과가 떴다.
import sys
input = sys.stdin.readline
N,M = map(int,input().split())
arr = [int(input()) for _ in range(N)]
for _ in range(M):
a,b = map(int,input().split())
print(min(arr[a-1:b]),max(arr[a-1:b]))
트리를 최솟값, 최댓값을 따로 만든다.
풀이 방법은 세그멘테이션 트리의 코드와 같음.
import sys
from math import *
input = sys.stdin.readline
def initMin(node,start,end):
if start == end:
treeMin[node] = arr[start]
return treeMin[node]
mid = (start+end)//2
treeMin[node] = min(initMin(node*2,start,mid),initMin(node*2+1,mid+1,end))
return treeMin[node]
def initMax(node,start,end):
if start == end:
treeMax[node] = arr[start]
return treeMax[node]
mid = (start+end)//2
treeMax[node] = max(initMax(node*2,start,mid),initMax(node*2+1,mid+1,end))
return treeMax[node]
#최소 구하기
def findMin(node,start,end,left,right):
if start > right or end < left:
return 1000000001
if left<=start and end <= right:
return treeMin[node]
mid = (start+end)//2
return min(findMin(node*2,start,mid,left,right),findMin(node*2+1,mid+1,end,left,right))
def findMax(node,start,end,left,right):
if start > right or end < left:
return 0
if left<=start and end <= right:
return treeMax[node]
mid = (start+end)//2
return max(findMax(node*2,start,mid,left,right),findMax(node*2+1,mid+1,end,left,right))
N,M = map(int,input().split())
arr = [int(input()) for _ in range(N)]
h = int(ceil(log2(N)))
t_size = 1<<(h+1)
treeMax = [0] * t_size
treeMin = [0] * t_size
#세그멘트 트리만들기
initMin(1,0,N-1)
initMax(1,0,N-1)
for _ in range(M):
a,b = map(int,input().split())
print(f'{findMin(1,0,N-1,a-1,b-1)} {findMax(1,0,N-1,a-1,b-1)}')
'알고리즘 공부' 카테고리의 다른 글
[백준/그리디] 22993번 서든어택3 (0) | 2022.03.17 |
---|---|
[백준/세그먼테이션 트리] 10868번 최솟값 (0) | 2022.03.16 |
[백준/세그먼트트리] 2042번 구간 합 (0) | 2022.03.15 |
[백준/플로이드와샬] 1956번 운동 (0) | 2022.03.14 |
[백준/최소신장트리] 20010번 악덕 영주 혜유 (0) | 2022.03.13 |