728x90
반응형
링크
https://www.acmicpc.net/problem/2042
2042번: 구간 합 구하기
첫째 줄에 수의 개수 N(1 ≤ N ≤ 1,000,000)과 M(1 ≤ M ≤ 10,000), K(1 ≤ K ≤ 10,000) 가 주어진다. M은 수의 변경이 일어나는 횟수이고, K는 구간의 합을 구하는 횟수이다. 그리고 둘째 줄부터 N+1번째 줄
www.acmicpc.net
해설
사실 이문제는 세그먼트 트리를 이용하거나 펜윅 트리를 이용하면 더욱 빠르게 구할 수 있습니다.
세그먼트 트리를 이용한 방법과 펜윅 트리를 이용한 방법 둘 다 나중에 올리겠습니다.
근데 제가 배우질 않아서 일단 full binary tree 를 이용해서 풀었습니다.
코드는 간단합니다.
입력수만큼 받고 2^n 까지 나머지를 0으로 채우고 full binary tree 로 만들면 됩니다.
그 후 각 노드들은 하위 2개노드의 합을 적어두고
만약 값이 바뀔경우 해당 노드와 상위 노드의 갑만 수정해주면 됩니다.
a ~ b 까지의 합을 구하는 방법은
1. 쪼개고 쪼개다가 최소 단위가 되었을 경우
2. 쪼개던 중 쪼개진 범위가 구해야 하는 범위 안에 다 들어갈 경우
위의 2가지 경우를 모두 더해주면 a ~ b 까지 합을 구할 수 있습니다.
코드
#include <iostream> using namespace std; int N, M, K, NUM = 1; long long TABLE[2097152]; long long sum(int _l, int _r, int _a, int _b, int _num) { if ((_l == _a && _r == _b) || _a == _b) return TABLE[_num]; int mid_left = (_a + _b - 1) / 2, list_num_left = _num * 2 + 1; if (_r <= mid_left) return sum(_l, _r, _a, mid_left, list_num_left); else if (mid_left < _l) return sum(_l, _r, mid_left + 1, _b, list_num_left + 1); else return sum(_l, mid_left, _a, mid_left, list_num_left) + sum(mid_left + 1, _r, mid_left + 1, _b, list_num_left + 1); } int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); cin >> N >> M >> K; int finish, start; while (NUM < N) NUM *= 2; start = NUM - 1; finish = start * 2; for (int i = start; i < start + N; ++i) cin >> TABLE[i]; for (int i = start + N; i <= finish; ++i) { TABLE[i] = 0; } for (int i = start - 1; i >= 0; --i) { int num = i * 2 + 1; TABLE[i] = TABLE[num] + TABLE[num + 1]; } for (int i = 0; i < M + K; ++i) { int first, second; cin >> first >> second; if (first == 1) { long long third; cin >> third; int number = start + second - 1; long long gap = third - TABLE[number]; while (true) { TABLE[number] += gap; if (number == 0) break; number = (number - 1) / 2; } } else { int third; cin >> third; cout << sum(second, third, 1, NUM, 0) << "\n"; } } return 0; }
728x90
반응형
'컴퓨터공학 > 백준' 카테고리의 다른 글
[백준][1103][C++] 게임 (0) | 2021.07.07 |
---|---|
[백준][1062][C++] 가르침 (0) | 2021.07.06 |
[백준][2580][C++] 스도쿠 (0) | 2021.07.04 |
[백준][1806][C++] 부분합 (0) | 2021.07.03 |
[백준][17298][C++] 오큰수 (0) | 2021.07.02 |