ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [백준] 5676 음주 코딩
    ALGORITHM/BOJ 2021. 2. 7. 16:55

    www.acmicpc.net/problem/5676

     

    5676번: 음주 코딩

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

    www.acmicpc.net

    2021-02-07


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.util.Arrays;
    import java.util.StringTokenizer;
     
    public class Main {
        public static int N, K, arr[], tree[];
     
        public static int init(int node, int start, int end) {
            // leaf node
            if(start == end) return tree[node] = arr[start];
     
            int mid = (start + end) / 2;
     
            return tree[node] = init(node*2, start, mid) * init(node*2+1, mid+1, end);
        }
     
        public static void update(int node, int start, int end, int idx, int change) {
            // idx out of range
            if(start > idx || end < idx) return;
     
            // leaf node
            if(start == end) {
                tree[node] = change;
                return;
            }
            // not leaf node
            if(start != end) {
                int mid = (start + end) / 2;
                update(node*2, start, mid, idx, change);
                update(node*2+1, mid+1, end, idx, change);
                tree[node] = tree[2*node] * tree[2*node+1];
            }
        }
     
        public static long multiple(int node, int start, int end, int left, int right) {
            // 1) left, right가 start, end 범위를 완전히 벗어났을 때
            if(left > end || right < start) return 1;
     
            // 2) left, right가 start, end를 완전히 포함하는 경우
            if(left <= start && end <= right) return tree[node];
     
            int mid = (start + end) / 2;
            return multiple(node*2, start, mid, left, right) *
                    multiple(node*2+1,mid+1, end, left, right);
        }
     
        public static void main(String[] args) throws Exception {
            BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
            String temp;
            while((temp = bf.readLine()) != null) {
                StringTokenizer st = new StringTokenizer(temp);
                N = Integer.parseInt(st.nextToken());
                K = Integer.parseInt(st.nextToken());
     
                arr = new int[N+1];
                tree = new int[N*4];
                st = new StringTokenizer(bf.readLine());
                // 루트 노드는 1부터 시작한다.
                for(int i = 1; i <= N; i++) {
                    int x = Integer.parseInt(st.nextToken());
                    if(x > 0) arr[i] = 1;
                    else if(x < 0) arr[i] = -1;
                    else arr[i] = 0;
                }
                // init
                init(11, N);
                StringBuilder sb = new StringBuilder();
                for(int i = 0; i < K; i++) {
                   st = new StringTokenizer(bf.readLine());
                   String order = st.nextToken();
                   int a = Integer.parseInt(st.nextToken());
                   int b = Integer.parseInt(st.nextToken());
     
                   if(order.equals("C")) { // change arr[a] <- b
                        if(b > 0) b = 1;
                        else if(b < 0) b = -1;
                        update(11, N, a, b);
                   } else { // delete
                        long answer = multiple(11, N, a, b);
                        if(answer > 0) sb.append("+");
                        else if(answer < 0) sb.append("-");
                        else sb.append("0");
                   }
                }
                System.out.println(sb.toString());
            }
        }
    }
    cs


    #문제풀이

     

    세그먼트 트리 문제이다. 일종의 구간 곱 구하기 인데, 입력값에서 받은 값 그대로 사용하면 스택오버플로우가 생긴다.

    그래서 각 값을 양수/음수/0으로 나누어서 아래와 같이 입력 값을 받고, update 할 때도 양수/음수/0으로 나누어서 그 값으로 값을 변경해야한다.

     

    양수 ->  1

    음수 -> -1

    0 -> 0

     

    'ALGORITHM > BOJ' 카테고리의 다른 글

    [백준] 1062 가르침  (0) 2021.02.15
    [백준] 1561 놀이공원  (0) 2021.02.13
    [백준] 14425 문자열 집합  (0) 2021.02.02
    [백준] 1238 파티  (0) 2021.01.31
    [백준] 1854 K번째 최단경로 찾기  (0) 2021.01.31

    댓글

Programming Diary