[백준] 10868: 최솟값 - JAVA

https://www.acmicpc.net/problem/10868

풀이

N개의 정수 배열의 a~b구간에서의 최솟값을 찾아야 한다.

세그먼트트리를 만들어 구간별로 최소값을 갖는 배열의 인덱스를 저장했다.

a~b구간에서 최솟값의 인덱스를 찾아 배열의 값을 출력하면 된다.

인덱스를 저장하지 않고 최솟값 자체를 세그먼트트리에 저장하는 것도 좋다.


메모리: 48788KB

시간: 600ms

언어: Java 11

코드

import java.util.*;
import java.io.*;

public class Main {
    static class SegmentTree {
        int[] tree;
        int treeSize;

        public SegmentTree(int arrSize) {
            int height = (int) Math.ceil(Math.log(arrSize) / Math.log(2));
            this.treeSize = (int) Math.pow(2, height + 1);
            tree = new int[treeSize];
        }

        public int init(int[] arr, int node, int start, int end) {
            if (start == end) {
                return tree[node] = start;
            } else {
                int a = init(arr, node * 2, start, (start + end) / 2);
                int b = init(arr, node * 2 + 1, (start + end) / 2 + 1, end);
                return tree[node] = arr[a] < arr[b] ? a : b;
            }
        }

        public int find(int[] arr, int node, int start, int end, int left, int right) {
            if (left > end || right < start) {
                return 0;
            }

            if (left <= start && end <= right) {
                return tree[node];
            }

            int a = find(arr, node * 2, start, (start + end) / 2, left, right);
            int b = find(arr, node * 2 + 1, (start + end) / 2 + 1, end, left, right);
            return arr[a] < arr[b] ? a : b;
        }
    }

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        int N = Integer.parseInt(st.nextToken());
        int M = Integer.parseInt(st.nextToken());
        int[] arr = new int[N + 1];
        for (int i = 1; i < N + 1; i++) {
            arr[i] = Integer.parseInt(br.readLine());
        }
        arr[0] = Integer.MAX_VALUE;

        SegmentTree seg = new SegmentTree(N);
        seg.init(arr, 1, 1, N);

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < M; i++) {
            st = new StringTokenizer(br.readLine());
            int a = Integer.parseInt(st.nextToken());
            int b = Integer.parseInt(st.nextToken());

            int idx = seg.find(arr, 1, 1, N, Math.min(a, b), Math.max(a, b));
            sb.append(arr[idx]).append("\n");
        }

        System.out.println(sb);
    }
}