https://school.programmers.co.kr/learn/courses/30/lessons/92344#qna

2022 카카오 신입 공채 1차 온라인 코딩테스트 for Tech developers 문제해설 - tech.kakao.com

Time Complexcity: O(N * M + K)

class Solution {
    public int solution(int[][] board, int[][] skill) {
        /*
        N <= 1000, M <= 1000
        skill.length <= 100
        O(N*M*100)
        */
        
        int[][] memo = new int[board.length+1][board[0].length+1];
        
        //K 아 이게 O(K)가 아니라 O(K*N)이네
        //개선: O(K*1). 즉, O(K)
        for(int[] skillElement : skill){
            int type = skillElement[0]; //1은 공격, 2는 회복
            int r1 = skillElement[1];
            int c1 = skillElement[2];
            int r2 = skillElement[3];
            int c2 = skillElement[4];
            int degree = skillElement[5]; //공격이나 회복 수치
            int value = 0;
            value = (type == 1) ? -1 * degree : degree;
        
            memo[r1][c1] += value;
            memo[r1][c2 + 1] -= value;
            memo[r2 + 1][c1] -= value;
            memo[r2 + 1][c2 + 1] += value;
 
            //O(N)
            // for(int i = r1 ; i <= r2 ; i++){
            //     memo[i][c1] += value;
            // }
            // for(int i = r1 ; i <= r2 ; i++){
            //     memo[i][c2+1] += (-1)*value;
            // }
        }
        //N*M
        for(int i=0 ; i<board.length ; i++){
            for(int j=1 ; j<board[0].length ; j++){
                memo[i][j] += memo[i][j-1];
            } 
        }
        //N*M
        for(int j=0 ; j<board[0].length ; j++){
            for(int i=1 ; i<board.length ; i++){
                memo[i][j] += memo[i-1][j];
            } 
        }
        int answer = 0;
        //N*M
        for(int i=0 ; i<board.length ; i++){
            for(int j=0 ; j<board[0].length ; j++){
                board[i][j] += memo[i][j];
                if(board[i][j] > 0) ++answer;
            }
        }
        
        return answer;
    }
}