백준공부

[백준] 2357번 최솟값과 최댓값 (gold 1

gomduri43 2024. 5. 28. 16:49

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

class Point{
    int min;
    int max;
    public Point(int min, int max){
        this.min=min;
        this.max=max;
    }
}

//최솟값, 동시에 최댓값을 고려해야하는 문제. 자바의 클래스를 이용해서 풀이함.
//참조값을 반환하기 때문에 이부분에서 실수하지 않도록 유의했다. 

class SegTree{
    Point[] tree;

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

    public Point init(int node, int start, int end, Point[] arr){
        if(start==end){
            return tree[node]=arr[start]; //arr에서 선언했던 참조값들을 가져옴.
        }

        Point a=init(node*2, start, (start+end)/2, arr);
        Point b=init(node*2+1, (start+end)/2+1, end, arr);
        //이 값들을 비교하여, 새로운 값을 출력해야 하므로, 객체 생성
        return tree[node]=new Point(Math.min(a.min, b.min) ,Math.max(a.max, b.max)); 
    }

    public Point find(int node, int start, int end, int left, int right){
        if(right<start || end<left){
            //범위 밖인 경우에 return값이 없으면 nullPointerException발생.
            //따라서, 새로 Point생성해서, 기존의 쿼리에 영향이 안가게 값들을 설정하여 반환한다.
            return new Point(Integer.MAX_VALUE, Integer.MIN_VALUE);
        }
        if(left<=start && end<=right){
            return tree[node];
        }

        //값들을 비교하여, 새로운 노드를 생성해야됨. 객체생성
        Point a=find(node*2, start, (start+end)/2, left, right);
        Point b=find(node*2+1, (start+end)/2+1, end ,left, right);
        return new Point(Math.min(a.min, b.min), Math.max(a.max, b.max));
    }
}

public class Main{
    public static void main(String[] args) throws IOException{
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(System.out));
        StringTokenizer st=new StringTokenizer(br.readLine());

        int n=Integer.valueOf(st.nextToken());
        int m=Integer.valueOf(st.nextToken());

        Point[] arr=new Point[n+1];
        for(int i=1; i<=n; i++){
            int temp=Integer.valueOf(br.readLine());
            arr[i]=new Point(temp, temp);
        }

        SegTree seg=new SegTree(n);
        seg.init(1,1,n,arr);

        for(int i=1; i<=m; i++){
            st=new StringTokenizer(br.readLine());
            int a=Integer.valueOf(st.nextToken());
            int b=Integer.valueOf(st.nextToken());
            Point temp=seg.find(1,1,n,Math.min(a,b), Math.max(a,b));
            bw.write(temp.min+" "+temp.max+"\n");
        }
        bw.flush();
    }
}