[백준] 5676.음주코딩 - 세그먼트 트리 (JAVA)

문제링크 🚩

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

 

5676번: 음주 코딩

각 테스트 케이스마다 곱셈 명령의 결과를 한 줄에 모두 출력하면 된다. 출력하는 i번째 문자는 i번째 곱셈 명령의 결과이다. 양수인 경우에는 +, 음수인 경우에는 -, 영인 경우에는 0을 출력한다.

www.acmicpc.net

 

📕 문제 접근 📕

-기존 세그먼트 트리와 매우 유사하지만 EOF 를 처리하는 유형의 문제이다

-  여러가지 방법이 존재하지만 본인의 경우 try - catch 방식을 활용하여 문제를 해결하였다.

- 문제에서 정확한 숫자가 아닌 음수 혹은 정수 혹은 0을 요구했기에 입력 받는 과정에서 음수면 - 양수면 +의 로직을 활용하였다.

 

 

💻 Code 💻

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;


public class BOJ_11505_re {
    static int[] arr;
    static int[] tree;

    public static void main(String[] args) throws IOException, NumberFormatException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;
        String input;
        StringBuilder sb = new StringBuilder();
        while (true) {
            try {
                st = new StringTokenizer(br.readLine());
                int n = Integer.parseInt(st.nextToken());
                int k = Integer.parseInt(st.nextToken());
                arr = new int[n + 1];
                tree = new int[n * 4];
                st = new StringTokenizer(br.readLine());
                for (int i = 1; i <= n; i++) {
                    int temp = Integer.parseInt(st.nextToken());
                    if (temp > 0) {
                        temp = 1;
                    } else if (temp < 0) {
                        temp = -1;
                    }
                    arr[i] = temp;
                }
                init(1, n, 1);
                while (k-- > 0) {
                    st = new StringTokenizer(br.readLine());
                    String oper = st.nextToken();
                    int i = Integer.parseInt(st.nextToken());
                    int v = Integer.parseInt(st.nextToken());
                    if (oper.equals("C")) { // update
                        if (v > 0) {
                            v = 1;
                        } else if (v < 0) {
                            v = -1;
                        }
                        update(1, n, 1, i, v);
                    } else { // 연산
                        int data = get(1, n, 1, i, v);
                        if (data > 0) {
                            sb.append("+");
                        } else if (data == 0) {
                            sb.append("0");
                        } else {
                            sb.append("-");
                        }
                    }
                }
                sb.append('\n');
            }catch (Exception e){
                break;
            }
        }
        System.out.println(sb);
    }

    private static void init(int start, int end, int node) {
        if (start == end) {
            tree[node] = arr[start];
            return;
        }
        int mid = (start + end) / 2;
        init(start, mid, node * 2);
        init(mid + 1, end, node * 2 + 1);
        tree[node] = tree[node * 2] * tree[node * 2 + 1];
    }

    private static int update(int start, int end, int node, int index, int value) {
        if (start > index || end < index) {
            return tree[node];
        }
        if (start == end) {
            return tree[node] = value;
        }
        int mid = (start + end) / 2;
        int l = update(start, mid, node * 2, index, value);
        int r = update(mid + 1, end, node * 2 + 1, index, value);
        return tree[node] = l * r;
    }

    private static int get(int start, int end, int node, int left, int right) {
        if (right < start || left > end) {
            return 1;
        }
        if (left <= start && right >= end) {
            return tree[node];
        }
        int mid = (start + end) / 2;
        return get(start, mid, node * 2, left, right) * get(mid + 1, end, node * 2 + 1, left, right);
    }
}

 

 

 

 

💻 Code Review💻

- try - catch 으로 처음 풀어봤는데 생각보다 획기적인 방법인 것 같다 

 

📖 배운점 📖