본문 바로가기
코딩캠프/BOJ

[2042] 구간 합 구하기

by 코곰_ 2024. 2. 15.
// 2042 구간 합 구하기 
// segment tree 
#include <bits/stdc++.h>
#define NMAX 1000000
using namespace std;

int N, M, K;

int a, b;
long long c; // 입력의 수는 -2^63 ~ 2^63-1 

int start;
long long ans;

long long tree[NMAX*3];

// 값 추가 되었을 때 업데이트  
// b번째 수를 c로 바꾼다.  
// 현재 값과 새로운 값의 차이만큼 루트노드로 올라가며 값을 갱신  
void update(int idx, long long value){
	// 값 교체  
	idx = idx + start;
	tree[idx] = value;
	// 그 위의 값들 갱신
	for(int p = idx/2; p > 0; p = p/2){
		tree[p] = tree[p*2] + tree[p*2+1];
	}
}

long long get(int left, int right){
	long long sum = 0;
	// 트리 배열의 인덱스로 변환  
	left = start + left; 
	right = start + right;
	
	while (left <= right){
		if(left % 2 == 1){ // L이 오른쪽에 있으면  
			sum = sum + tree[left]; // sum에 합치고 올라감  
			left ++;
		} 
		if(right % 2 == 0){ // R이 왼쪽에 있으면  
			sum = sum + tree[right]; // sum에 합치고 올라감  
			right --;
		}
		
		// 부모로 올라감  
		left = left / 2;
		right = right / 2;
	}
	return sum;
}

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	
	cin >> N >> M >> K;
	int treesize = 1;
	
	while (treesize < N){
		// 노드가 전부 들어갈 트리 사이즈 찾기  
		treesize = treesize * 2;
	}
	memset(tree, 0, treesize * 2 +1);
	start = treesize - 1; // 트리 인덱스를 찾기 위한 값  
	
	// leaf 영역 채우기 
	for(int i=1; i<=N; ++i){
		long long inp;
		cin >> inp;
		tree[start+i] = inp;
	} 
	
	// leaf 제외한 영역 채우기 
	for(int i=start; i!=0; i--){ // 아래 -> 위로 채우기  
		tree[i] = tree[i*2] + tree[i*2+1];
	} 
	
	for(int i=0; i<M+K; ++i){
		cin >> a >> b >> c;
		
		// 업데이트  
		if(a == 1){
			update(b, c);
		}
		// 구간합 구하기  
		else if (a == 2){
			ans = get(b, c);
			cout << ans << "\n";
		}	
	}
	return 0;
}

'코딩캠프 > BOJ' 카테고리의 다른 글

[2252] 줄 세우기  (1) 2024.02.19
[1717] 집합의 표현  (0) 2024.02.19
[1991] 트리순회  (0) 2024.02.14
[2096] 내려가기  (0) 2024.02.14
[1927] 최소힙  (1) 2024.02.14