구름이가 사는 마을에는 1번 집부터 번 집까지 총 V개의 집이 순서대로 세워져 있다.
마을의 땅 높이는 제각각이어서, 번째 집의 땅 높이는 K; 이다. 땅 높이의 기준은 해수면이기 때문에, 해수면보다 낮은 위치에 집이 있다면 높이가 음수일 수도 있다.
장마가 시작되면 MM 일 동안 멈추지 않고 비가 온다. 장마가 시작된 지 i일이 되는 날에는
5; 번 집이 있는 위치부터 ex번 집이 있는 위치까지 비가 내린다. 어떤 집에 비가 내리면 그 집에 쌓인 물의 높이가 1만큼 증가한다. 한 번 쌓인 물은 배수 시스템이 작동하기 전까지는 빠지지 않는다.
배수 시스템은 장마가 시작된 지 3의 배수가 되는 날마다, 비가 내리고 난 뒤 작동한다.
배수 시스템은 작동 날짜를 기준으로 2일 이내에 비가 내린 위치에서만 작동한다. 예를 들어, 장마가 시작되고 9일째에 작동하는 배수 시스템은 7, 8, 9일 째에 비가 내린 위치에서만 작동한다. 배수 시스템이 작동하면 그 집에 쌓인 물의 높이가 1만큼 감소한다.
장마가 지나간 뒤, 마을의 모든 땅 높이는 그 땅에 쌓였던 물의 높이만큼 증가한다.
구름이는 1번 집부터 번 집까지의 땅 높이를 다시 조사하려고 한다. 구름이를 도와 변한 땅 높이를 구해보자.
첫째 줄에 집의 개수 N과 장마 기간 M이 공백을 두고 주어진다.
둘째 줄에 마을의 땅 높이 k1, k2,..., kN이 공백을 두고 주어진다.
다음 M 개의 줄에는 si, ei가 공백을 두고 주어진다. 장마가 시작된 지 i일이 되는 날에는 5; 번 집이 있는 위치부터 번 집이 있는 위치까지 비가 내렸다는 의미이다.
• 1 ≤ N ≤ 1,000
• 1 ≤ M ≤ 100,000
• -100,000 ≤ ki ≤ 100,000
• 1 ≤ si ≤ ei ≤ N
• 입력에서 주어지는 모든 수는 정수이다.
장마가 끝난 뒤, 1번 집부터 번 집까지의 땅 높이를 한 줄에 하나씩 출력한다.
5 5
-1 0 1 0 2
1 1
2 2
3 3
4 5
4 5
-1 0 1 2 4
5 7
0 0 0 0 0
1 5
1 5
1 5
1 5
1 5
1 5
1 2
5 5 4 4 4
const readline = require('readline');
(async () => {
const rl = readline.createInterface({ input: process.stdin });
let input = [];
for await (const line of rl) {
// 입력의 각 라인을 불러오고, trim()을 통해 시작과 끝에 있을 수 있는 공백을 삭제하고 input 배열에 push 한다
input.push(line.trim());
}
rl.close();
// input 배열의 0 자리에 있는 두 숫자를 destructuring 해서 지정한다.
const [houseNum, rainDays] = input[0].split(' ').map(Number); // houseNum = 5, rainDays = 5
// input 배열의 1 자리에 있는 각 집의 높이가 저장된 요소를 불러와서 숫자로 띄어쓰기를 기준으로 나눠서 배열 요소로 집어 넣는다.
let houseHeight = input[1].split(' ').map(Number); // [-1, 0, 1, 0, 2]
// input 배열의 첫 요소를 없애고, 비가 온 집들의 위치만 넣는다.
let forecast = input.slice(2); // forecast = ['1 1', '2 2',... '4 5']
let waterHeight = Array(houseNum).fill(0); // waterHeight = [0, 0, 0, 0, 0]
// recentRain 안에 set을 사용해서 당일을 포함해서 최근 3일간 비가 온 집의 인덱스를 set에 추가한다. 이 set은 배수 시스템이 작동하면 clear된다.
let recentRain = new Set();
// 비가 온 집의 물 높이를 계산
// 먼저 비가 온 날을 기준
for (let day = 0; day < rainDays; day++) {
// forecast 배열에 있는 각 비가 온 날의 비가 온 시작 집과 끝 집을 destructuring으로 가져온다.
let [startPosition, endPosition] = forecast[day].split(' ').map(Number); // forecast[0] 일때 startPosition = 1, endPostion = 1
startPosition -= 1; // 배열의 위치는 0 부터 시작하기에 0으로 부터 시작하는 걸로 계산
endPosition -= 1; // 배열의 위치는 0 부터 시작하기에 0으로 부터 시작하는 걸로 계산
// 시작 집부터 끝 집까지 물 높이와 비가 온 날을 추가해준다.
for (let i = startPosition; i <= endPosition; i++) {
// 물 높이 추가
waterHeight[i]++;
// 비가 온 집의 인덱스를 set에 추가한다.
recentRain.add(i);
}
// 3번 째 비오는 날 마다 배수 시스템 작동
if ((day + 1) % 3 === 0) {
// set 안에 저장된 집들을 하나씩 불러온다.
for (let j of recentRain) {
// 물 높이를 1씩 줄여주고, 0보다 작지 않게 해준다.
waterHeight[j] = Math.max(0, waterHeight[j] - 1);
}
// set을 clear하여 다음 비오는 사이클을 위해 비워준다.
recentRain.clear();
}
}
// 각 집마다 물 높으만큼 땅 높이를 높여 준다.
for (let i = 0; i < houseHeight.length; i++) {
houseHeight[i] += waterHeight[i];
}
// 배열로 저장된 땅 높이를 하나의 String으로 합쳐서 반환한다.
console.log(houseHeight.join(' '));
process.exit();
})();