BOJ 2357

최솟값과 최댓값

문제출처

문제 해석

  • N개의 정수들이 있을 때, [a,b]범위에 있는 최솟값과 최댓값을 출력하는 문제입니다.

설계(5)

  • 최댓값과 최솟값의 세그먼트트리를 만들어 각 구간의 최솟값과 최댓값을 저장한 후, 출력하면 됩니다.
  • 여기서 주의할 점은 최대,최솟값을 찾을 때 범위를 완전히 벗어나는 경우에 최대는 최솟값으로 리턴해주어야 하고, 최소는 최댓값으로 리턴해주어야 합니다.

구현(15)

코드
#include <iostream>
#include <vector>
#include <math.h>
using namespace std;
#define MAXN 100001
#define INF 1000000001
int arr[MAXN];
vector<int> min_tree;
vector<int> max_tree;
int N,M;

int init(vector<int>& tree, int node, int start, int end, int mode){
    if (start == end) return tree[node] = arr[start];
    int mid = (start+end)/2;
    if (mode==0){
        return tree[node] = min(init(tree,node*2,start,mid,mode),init(tree,node*2+1,mid+1,end,mode));
    }
    else{
        return tree[node] = max(init(tree,node*2,start,mid,mode),init(tree,node*2+1,mid+1,end,mode));
    }
}
int calc(vector<int>& tree, int node, int start, int end, int left, int right, int mode){
    if (left> end || right < start) {
        // 최솟값 구할 경우 INF로 리턴
        if (mode ==0) return INF;
        // 최댓값 구할 경우 0으로 리턴
        else return 0;
    }
    if (left <= start && end <= right) return tree[node];
    int mid = (start + end) / 2;
    if (mode==0){
        return min(calc(tree,node*2,start,mid,left,right,mode),calc(tree,node*2+1,mid+1,end,left,right,mode));
    }
    else{
        return max(calc(tree,node*2,start,mid,left,right,mode),calc(tree,node*2+1,mid+1,end,left,right,mode));
    }
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin >> N >> M;
    for (int i = 0; i <N;i++){
        cin >> arr[i];
    }
    int h = 1;
    while (h < N) h <<= 1;
    min_tree = vector<int>(h*2);
    max_tree = vector<int>(h*2);
    init(min_tree,1,0,N-1,0);
    init(max_tree,1,0,N-1,1);
    while (M--){
        int left,right;
        cin >> left >> right;
        left--;
        right--;
        cout << calc(min_tree,1,0,N-1,left,right,0) << " " << calc(max_tree,1,0,N-1,left,right,1) <<"\n";
    }
    return 0;
}
디버깅
제출결과
  • 140ms

마무리

  • 세그먼트 트리는 어느 구간의 정보를 추출할 때 아주 용이한 알고리즘인 것 같습니다. 최대와 최솟값을 찾는데도 아주 최적화가 잘 되어있습니다.