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

문제가 좀 많이 어렵네요.

 

세그먼트 트리 + lazy propagation 알고리즘인데... 습 좀 많이 어렵네요.

관련해서 오답노트 정리 해볼 예정입니다.

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

public class Main {
    static int n;
    static long[] tree;
    static long[] lazy;

    public static void initTree(long[] arr) {
        buildTree(0, n - 1, 1, arr);
    }

    public static long buildTree(int start, int end, int node, long[] arr) {
        if (start == end) {
            return tree[node] = arr[start];
        }

        int mid = (start + end) / 2;
        return tree[node] = buildTree(start, mid, node * 2, arr) + buildTree(mid + 1, end, node * 2 + 1, arr);
    }

    public static void updateRange(int start, int end, int node, int rangeStart, int rangeEnd, long diff) {
        if (lazy[node] != 0) {
            tree[node] += (end - start + 1) * lazy[node];
            if (start != end) {
                lazy[node * 2] += lazy[node];
                lazy[node * 2 + 1] += lazy[node];
            }
            lazy[node] = 0;
        }

        if (rangeStart > end || rangeEnd < start) {
            return;
        }

        if (rangeStart <= start && end <= rangeEnd) {
            tree[node] += (end - start + 1) * diff;
            if (start != end) {
                lazy[node * 2] += diff;
                lazy[node * 2 + 1] += diff;
            }
            return;
        }

        int mid = (start + end) / 2;
        updateRange(start, mid, node * 2, rangeStart, rangeEnd, diff);
        updateRange(mid + 1, end, node * 2 + 1, rangeStart, rangeEnd, diff);
        tree[node] = tree[node * 2] + tree[node * 2 + 1];
    }

    public static long queryRange(int start, int end, int node, int queryStart, int queryEnd) {
        if (lazy[node] != 0) {
            tree[node] += (end - start + 1) * lazy[node];
            if (start != end) {
                lazy[node * 2] += lazy[node];
                lazy[node * 2 + 1] += lazy[node];
            }
            lazy[node] = 0;
        }

        if (queryStart > end || queryEnd < start) {
            return 0;
        }

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

        int mid = (start + end) / 2;
        return queryRange(start, mid, node * 2, queryStart, queryEnd) + queryRange(mid + 1, end, node * 2 + 1, queryStart, queryEnd);
    }

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
       
        StringTokenizer st = new StringTokenizer(br.readLine());

        n = Integer.parseInt(st.nextToken());
        int m = Integer.parseInt(st.nextToken());
        int k = Integer.parseInt(st.nextToken());

        long[] arr = new long[n];
        for (int i = 0; i < n; i++) {
            arr[i] = Long.parseLong(br.readLine());
        }

        tree = new long[n * 4];
        lazy = new long[n * 4];

        initTree(arr);

        for (int i = 0; i < m + k; i++) {
            st = new StringTokenizer(br.readLine());
            int type = Integer.parseInt(st.nextToken());
            if (type == 1) {
                int b = Integer.parseInt(st.nextToken()) - 1;
                int c = Integer.parseInt(st.nextToken()) - 1;
                long d = Long.parseLong(st.nextToken());
                updateRange(0, n - 1, 1, b, c, d);
            } else if (type == 2) {
                int b = Integer.parseInt(st.nextToken()) - 1;
                int c = Integer.parseInt(st.nextToken()) - 1;
                long result = queryRange(0, n - 1, 1, b, c);
                System.out.println(result);
            }
        }

    }
}

'알고리즘 공부' 카테고리의 다른 글

백준 수열과 쿼리 37  (2) 2024.07.15
백준 커피숍2  (0) 2024.04.17
백준 가계부  (0) 2024.04.10
백준 쵯소값과 최댓값  (0) 2024.04.08
백준 구간 합 구하기  (0) 2024.04.04

+ Recent posts