2042 구간 합 구하기
2019. 10. 30. 16:05ㆍ알고리즘/백준
기본적인 배열을 통한 누적합은 구간합을 구하는 데 O(1)의 짧은 시간복잡도가 걸리지만 값이 변경됐을 때는 최대 N번을 통해 변경을 해야므로, 변경을 한 후 누적합을 구하는 시간복잡도는 O(N)이라고 할 수 있다. 하지만 세그먼트 트리를 구하면 O(lgN)만에 연산을 끝낼 수 있다
문제: https://www.acmicpc.net/problem/2042
깃허브주소: https://github.com/surinoel/boj/blob/master/2042.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <cmath> | |
#include <iostream> | |
using namespace std; | |
typedef long long ll; | |
int *arr; | |
ll *tree; | |
ll init(int idx, int start, int end) { | |
if(start == end) { | |
return tree[idx] = arr[start]; | |
} | |
else { | |
return tree[idx] = init(idx*2 + 1, start, (start + end)/2) + | |
init(idx*2 + 2, (start+end)/2 + 1, end); | |
} | |
} | |
ll sum(int idx, int start, int end, int left, int right) { | |
if(start > right || left > end) return 0; | |
else if(left <= start && end <= right) return tree[idx]; | |
else { | |
int mid = (start + end) / 2; | |
return sum(idx*2 + 1, start, mid, left, right) + | |
sum(idx*2 + 2, mid + 1, end, left, right); | |
} | |
} | |
void change(int idx, int start, int end, ll diff, int changeidx) { | |
if(changeidx < start || changeidx > end) return; | |
tree[idx] += diff; | |
if(start < end) { | |
int mid = (start + end) / 2; | |
change(2*idx + 1, start, mid, diff, changeidx); | |
change(2*idx + 2, mid + 1, end, diff, changeidx); | |
} | |
} | |
int main(void) { | |
ios_base::sync_with_stdio(false); | |
cin.tie(0); | |
int n, m, k; | |
cin >> n >> m >> k; | |
arr = new int[n]; | |
for(int i=0; i<n; i++) { | |
cin >> arr[i]; | |
} | |
int h = (int)ceil(log2(n)); | |
int tree_size = 1 << (h + 1); | |
tree = new ll[tree_size]; | |
init(0, 0, n-1); | |
for(int i=0; i<m+k; i++) { | |
int a; | |
ll b, c; | |
cin >> a >> b; | |
b -= 1; | |
if(a==1) { | |
cin >> c; | |
ll diff = c - arr[b]; | |
change(0, 0, n-1, diff, b); | |
arr[b] = c; | |
} | |
else { | |
cin >> c; | |
c -= 1; | |
cout << sum(0, 0, n-1, b, c) << '\n'; | |
} | |
} | |
delete[] arr; | |
delete[] tree; | |
return 0; | |
} |
'알고리즘 > 백준' 카테고리의 다른 글
17836 공주님을 구해라! (0) | 2019.11.13 |
---|---|
[삼성] 17825 주사위 윷놀이 (1) | 2019.11.05 |
[삼성] 17780 새로운 게임 (0) | 2019.10.28 |
[삼성] 17822 원판돌리기 (0) | 2019.10.26 |
[삼성] 17779 게리멘더링 2 (0) | 2019.10.24 |