티스토리 뷰
2차원 펜윅트리로 풀 수 있는 문제다.
펜윅트리를 2차원으로 생각하면 x축으로 펜윅트리가 있고
그 x축을 가진 y축 펜윅트리가 있다고 생각하면 편하다
업데이트와 합을 구할 때는 2중 포문으로
x축을 먼저 업데이트 해주고
그에 맞게 y축을 업데이트 해주면 된다
(a,b) ~ (x,y) 에 대한 합을 구하는건 그림을 그려보면 이해하기 쉽다
(x,y) 까지의 합에서 - (a-1,y) - (x,b-1) + (a-1,b-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 41 42 43 44 45 46 47 48 49 50 51 52 | #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <stack> #include <cstring> #include <set> #include <map> #include <cstring> #include <string> using namespace std; int tree[1111][1111]; int n, m; int sum(int x, int y) { int ret = 0; for (int i = x; i > 0; i -= (i&-i)) { for (int j = y; j > 0; j -= (j&-j)) { ret += tree[i][j]; } } return ret; } void update(int x, int y, int val) { for (int i = x; i <= n; i += (i&-i)) { for (int j = y; j <= n; j += (j&-j)) { tree[i][j] += val; } } } int main() { scanf(" %d %d", &n, &m); for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { int x; scanf(" %d", &x); update(i, j, x); } } for (int i = 0; i < m; i++) { int c; scanf(" %d", &c); if (c == 0) { int x, y, z; scanf(" %d %d %d", &x, &y, &z); int def = sum(x, y) - sum(x - 1, y) - sum(x, y - 1) + sum(x - 1, y - 1); update(x, y, z-def); } else { int a, b, x, y; scanf(" %d %d %d %d", &a, &b, &x, &y); printf("%d\n", sum(x, y)-sum(a-1,y) - sum(x,b-1) + sum(a-1,b-1)); } } } | cs |
'알고리즘 > BOJ' 카테고리의 다른 글
[백준] 5012 불만정렬 (2) | 2018.06.22 |
---|---|
[백준] 12016 라운드 로빈 스케줄러 (0) | 2018.06.22 |
[백준] 9466 텀 프로젝트 (0) | 2018.06.18 |
[백준] 2336 굉장한 학생 (0) | 2018.06.17 |
[백준] 12930 두 가중치 (0) | 2018.06.16 |
댓글