https://www.acmicpc.net/problem/2357
해당 문제는 수열의 특정 구간 내의 최솟값과 최댓값을 구하는 문제로, 세그먼트 트리 알고리즘을 사용하여 풀이했다.
1) 수열을 저장할 datas
, 최솟값 트리를 저장할 minTree
배열, 최댓값 트리를 저장할 maxTree
배열을 선언한다. 이 때 트리들의 크기는 수열 배열의 최대 크기의 4배 이상으로 설정한다.
2) 수의 개수 n
과 최솟값 및 최댓값을 구해야하는 범위의 개수 m
을 입력 받아 저장하고, n개의 수를 입력받아 datas
에 저장한다.
3) minInit()
, maxInit()
함수를 통해 최솟값 트리와 최댓값 트리를 초기화 한다.
4) m
번의 최솟값 및 최댓값 출력을 실행한다.
findMin()
과 findMax()
함수를 통해 현재 순서에서 구해야하는 범위의 최솟값 및 최댓값을 구한다.findMin()
을 실행한다.findMax()
을 실행한다.#include <iostream>
#include <algorithm>
using namespace std;
int n, m;
long long minTree[400004];
long long maxTree[400004];
long long datas[100001];
const long long INF = 1000000001;
long long minInit(int start, int end, int node)
{
if (start == end) return minTree[node] = datas[start];
int mid = start + (end - start) / 2;
return minTree[node] = min(minInit(start, mid, node * 2), minInit(mid + 1, end, node * 2 + 1));
}
long long findMin(int start, int end, int node, int left, int right)
{
if (end < left || right < start) return INF;
if (left <= start && end <= right) return minTree[node];
int mid = start + (end - start) / 2;
return min(findMin(start, mid, node * 2, left, right),
findMin(mid + 1, end, node * 2 + 1, left, right));
}
long long maxInit(int start, int end, int node)
{
if (start == end) return maxTree[node] = datas[start];
int mid = start + (end - start) / 2;
return maxTree[node] = max(maxInit(start, mid, node * 2), maxInit(mid + 1, end, node * 2 + 1));
}
long long findMax(int start, int end, int node, int left, int right)
{
if (end < left || right < start) return 0;
if (left <= start && end <= right) return maxTree[node];
int mid = start + (end - start) / 2;
return max(findMax(start, mid, node * 2, left, right),
findMax(mid + 1, end, node * 2 + 1, left, right));
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr); cout.tie(nullptr);
cin >> n >> m;
for (int i = 1; i <= n; i++)
cin >> datas[i];
minInit(1, n, 1);
maxInit(1, n, 1);
for (int i = 0; i < m; i++)
{
int a, b;
cin >> a >> b;
if (a < b)
{
cout << findMin(1, n, 1, a, b) << ' ';
cout << findMax(1, n, 1, a, b) << '\n';
}
else
{
cout << findMin(1, n, 1, b, a) << ' ';
cout << findMax(1, n, 1, b, a) << '\n';
}
}
}