https://www.acmicpc.net/problem/2357
아래의 최솟값 구하는 문제와 거의 유사하다.
https://www.acmicpc.net/problem/10868
다만 최솟값과 최댓값 둘다 구해야하므로 각 노드를 pair로 { 최솟값, 최댓값 }으로 보관하게 변경만 하고 제출해서 통과됐다.
정답코드)
#include <bits/stdc++.h>
using namespace std;
vector<int> arr;
vector<pair<int, int>> SegmentTree; // 최소값, 최대값 순으로 보관
void Make_SegmentTree(int Node, int Start, int End)
{
if (Start == End) { // 값 하나니까 최소값도 최대값도 본인 값
SegmentTree[Node].first = arr[Start];
SegmentTree[Node].second = arr[Start];
}
else {
Make_SegmentTree(Node * 2, Start, (Start + End) / 2);
Make_SegmentTree(Node * 2 + 1, (Start + End) / 2 + 1, End);
SegmentTree[Node].first = min(SegmentTree[Node * 2].first, SegmentTree[Node * 2 + 1].first);
SegmentTree[Node].second = max(SegmentTree[Node * 2].second, SegmentTree[Node * 2 + 1].second);
}
}
pair<int, int> SearchMinMax(int Node, int Start, int End, int Left, int Right) {
if (Left > End || Right < Start) return { 0, 0 }; // 값 범위에 0은 못나오니까 예외로 두려고 사용
if (Left <= Start && End <= Right) return SegmentTree[Node];
pair<int, int> Left_Result = SearchMinMax(Node * 2, Start, (Start + End) / 2, Left, Right);
pair<int, int> Right_Result = SearchMinMax(Node * 2 + 1, (Start + End) / 2 + 1, End, Left, Right);
if (Left_Result == make_pair(0, 0)) return Right_Result;
else if (Right_Result == make_pair(0, 0)) return Left_Result;
else return { min(Left_Result.first, Right_Result.first), max(Left_Result.second, Right_Result.second)};
}
int main()
{
ios::sync_with_stdio(false); cin.tie(NULL);
int N, M;
cin >> N >> M;
// 입력받고
arr.resize(N);
for (int i = 0; i < N; i++) {
cin >> arr[i];
}
// 세그먼트트리 만들고
int Tree_Height = (int)ceil(log2(N));
int Tree_Size = (1 << (Tree_Height + 1));
SegmentTree.resize(Tree_Size);
Make_SegmentTree(1, 0, N - 1);
// 요청받고
int a, b;
while(M--) {
cin >> a >> b;
// a에서 b까지 최소값과 최대값 출력, 인덱스니까 a, b 1씩 빼주기
pair<int, int> result = SearchMinMax(1, 0, N - 1, a - 1, b - 1);
cout << result.first << ' ' << result.second << '\n';
}
return 0;
}