문제
- 문제 링크
BOJ 25978 - 2차원 배열 다중 업데이트 다중 합
$n*n$ 크기의 행렬과, 두가지 유형으로 이루어진 $m$개의 쿼리가 주어진다.
유형 $2$의 쿼리가 주어질 때마다 그 결과를 출력해보자.
TL : $3$ sec, ML : $512$ MB
$1 ≤ n ≤ 1,000$ $1 ≤ k ≤ 10,000$ $1 ≤ m ≤ 300,000$ $1 ≤ n_{ij} ≤ 1,000,000$ 모든 유형 $1$의 질의가 유형 $2$의 질의보다 앞부분에 저장되어 있다.
알고리즘 분류
- 누적 합
풀이
"모든 유형 $1$의 질의가 유형 $2$의 질의보다 앞부분에 저장되어 있다."
위 조건이 없었다면 $2D$ $Segment$ $Tree$ $+$ $Lazy$ $Propagation$을 박아야 하나$?$ 싶을 수 있지만, 출력 요청 쿼리가 모든 업데이트 뒤에서야 등장한다.
이로 인해 $imos$법 사용을 고려해볼 수 있게 된다.
위 테크닉 또는 $2$차원 상의 누적 합을 다루는 것에 익숙치 않다면, 다음 두 문제정도 선행해보는 것을 추천한다.
$1$차원에서, 구간 $[x, y]$에 업데이트를 진행해야 한다면 $cnt[x]$에 $+$를, $cnt[y + 1]$에 $-$를 더해주고 최종적으로 스위핑해주어 결과를 얻을 수 있었다.
$2$차원은 결국 $1$차원의 확장이다.
임의의 업데이트에 대해 영향 받는 포인트들을 어디에 찍어야 할지 생각해보자.
앞서 언급한 두 문제를 적절히 섞어주면 된다.
구체적으로, $Q$_$[1, y1, x1, y2, x2, k]$에 대해
이후 첫번째 유형 $2$ 쿼리를 마주한 순간 위에서 아래로, 왼 쪽에서 오른 쪽으로 스위핑 해 업데이트를 끝낸 후 쿼리 당 $O(1)$로 응답할 수 있다.
직사각형 단위로 잘라보면 식을 정리할 수 있는데, 자세한 내용은 아래 코드를 참조하자.
전체 코드
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 | #include<bits/stdc++.h> using namespace std; long long sum[1005][1005], cnt[1005][1005]; void f(int n) { for (int i(1); i <= n; i++) for (int j(1); j <= n; j++) { cnt[i][j] += cnt[i - 1][j] + cnt[i][j - 1] - cnt[i - 1][j - 1]; sum[i][j] += sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + cnt[i][j]; } } int main() { ios_base::sync_with_stdio(0); cin.tie(0); int n, m; cin >> n >> m; for (int i(1); i <= n; i++) for (int j(1); j <= n; cin >> sum[i][j++]); for (int flag{}; m--;) { int o, y1, x1, y2, x2, k; cin >> o >> y1 >> x1 >> y2 >> x2; y1++, x1++, y2++, x2++; if (o & 1) { cin >> k; cnt[y1][x1] += k, cnt[y2 + 1][x2 + 1] += k; cnt[y1][x2 + 1] -= k, cnt[y2 + 1][x1] -= k; } else { if (!flag) flag = 1, f(n); cout << sum[y2][x2] - sum[y2][x1 - 1] - sum[y1 - 1][x2] + sum[y1 - 1][x1 - 1] << '\n'; } } } | cs |
comment
끝
'Problem Solving > Baekjoon Online Judge (Gold)' 카테고리의 다른 글
백준 28333 - 화이트 칼라 (C++) (0) | 2023.07.20 |
---|---|
백준 14757 - Dueling Philosophers (C++) (1) | 2023.07.16 |
백준 28019 - 산지니의 여행계획 (C++) (0) | 2023.06.28 |
백준 28251 - 나도리합 (C++) (0) | 2023.06.26 |
백준 27519 - 소수의 합 (C++) (0) | 2023.06.15 |