반응형
2042번: 구간 합 구하기
첫째 줄에 수의 개수 N(1 ≤ N ≤ 1,000,000)과 M(1 ≤ M ≤ 10,000), K(1 ≤ K ≤ 10,000) 가 주어진다. M은 수의 변경이 일어나는 횟수이고, K는 구간의 합을 구하는 횟수이다. 그리고 둘째 줄부터 N+1번째 줄
www.acmicpc.net
세그먼트 트리
세그먼트 트리(Segment Tree) 구간 쿼리와 수정이 빈번하게 일어나는 상황에서 유용하게 사용할 수 있는 자료구조입니다. 배열의 특정 구간에 대한 정보를 빠르게 구하거나 업데이트할 때 사용되며
flrjtwjrjt.tistory.com
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
static vector<long> tree;
long getSum(int s, int e);
void changeVal(int index, long val);
void setTree(int i);
int main()
{
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int N, M, K;
cin >> N >> M >> K;
int treeHeight = 0;
int Length = N;
while (Length != 0) {
Length /= 2;
treeHeight++;
}
int treeSize = int(pow(2, treeHeight + 1));
//int treeSize = 2;
//for (int i = 1; i < treeHeight + 1; i++)
// treeSize *= 2;
int startNodeIndex = treeSize / 2 - 1;
tree.resize(treeSize + 1);
for (int i = startNodeIndex + 1; i <= startNodeIndex + N; i++)
{
cin >> tree[i];
}
setTree(treeSize - 1);
for (int i = 0; i < M + K; i++)
{
long a, s, e;
cin >> a >> s >> e;
if (a == 1) {
changeVal(startNodeIndex + s, e);
}
else if (a == 2){
cout << getSum(startNodeIndex + s, startNodeIndex + e) << "\n";
}
}
}
long getSum(int s, int e)
{
long result = 0;
while (s <= e)
{
if (s % 2 == 1)
{
result += tree[s];
s++;
}
if (e % 2 == 0)
{
result += tree[e];
e--;
}
s /= 2;
e /= 2;
}
return result;
}
void changeVal(int s, long value)
{
long diff = value - tree[s];
while (s > 0)
{
tree[s ] += diff;
s /= 2;
}
}
void setTree(int i)
{
while (i != 1)
{
tree[i / 2] += tree[i];
i--;
}
}
반응형
LIST
'알고리즘 문제 > 백준' 카테고리의 다른 글
11505 구간 곱 구하기 (세그먼트 트리) [Gold I] (0) | 2024.04.24 |
---|---|
10868 최솟값 (세그먼트 트리)[Gold I] (0) | 2024.04.23 |
1991 트리 순회 (트리 순회)[Silver I] (0) | 2024.04.21 |
14425 문자열 집합 (Trie) [Silver IV] (0) | 2024.04.20 |
13023 ABCDE (DFS) (0) | 2023.04.04 |