
문제 링크
2042번: 구간 합 구하기
첫째 줄에 수의 개수 N(1 ≤ N ≤ 1,000,000)과 M(1 ≤ M ≤ 10,000), K(1 ≤ K ≤ 10,000) 가 주어진다. M은 수의 변경이 일어나는 횟수이고, K는 구간의 합을 구하는 횟수이다. 그리고 둘째 줄부터 N+1번째 줄
www.acmicpc.net
풀이
세그먼트 트리 또는 펜윅 트리 기본 문제이다.
개념을 설명은 다른 분이 잘해놓으셔서 생략하겠다.
코드
세그먼트 트리
#include <cstdio>
using ll = long long;
ll arr[1000006];
ll tree[4000006];
ll init(ll node, ll start, ll end) {
if (start == end) return tree[node] = arr[start];
ll mid = (start + end) / 2;
ll left = init(node * 2, start, mid);
ll right = init(node * 2 + 1, mid + 1, end);
return tree[node] = left + right;
}
ll sum(ll node, ll start, ll end, ll left, ll right) {
if (start > right || end < left) return 0;
if (left <= start && end <= right) return tree[node];
ll mid = (start + end) / 2;
return sum(node * 2, start, mid, left, right) + sum(node * 2 + 1, mid + 1, end, left, right);
}
void update(ll start, ll end, ll node, ll index, ll dif) {
if (index < start || index > end) return;
tree[node] += dif;
if (start == end) return;
ll mid = (start + end) / 2;
update(start, mid, node * 2, index, dif);
update(mid + 1, end, node * 2 + 1, index, dif);
}
int main() {
ll N, M, K; scanf("%lld %lld %lld", &N, &M, &K);
for (ll i = 0; i < N; i++)
scanf("%lld", arr + i);
init(1, 0, N - 1);
for (ll i = 0; i < M + K; i++) {
ll a, b, c; scanf("%lld %lld %lld", &a, &b, &c);
if (a == 1) {
ll dif = c - arr[b - 1];
arr[b - 1] = c;
update(0, N - 1, 1, b - 1, dif);
} else {
printf("%lld\n", sum(1, 0, N - 1, b - 1, c - 1));
}
}
}
펜윅트리
#include <cstdio>
#include <cstring>
using ll = long long;
struct Fenwick {
Fenwick(ll size) : size(size) { memset(tree, 0, sizeof tree); }
ll tree[1000006], size;
void update(ll i, ll diff) {
while (i < size) {
tree[i] += diff;
i += (i & -i);
}
}
ll query(ll i) {
ll ret = 0;
while (i > 0) {
ret += tree[i];
i -= (i & -i);
}
return ret;
}
};
ll arr[1000006];
int main() {
ll n, m, k; scanf("%lld %lld %lld", &n, &m, &k);
Fenwick fenwick = Fenwick(n + 1);
for (ll i = 1; i <= n; i++) {
scanf("%lld", arr + i);
fenwick.update(i, arr[i]);
}
ll q = m + k;
while (q--) {
ll k, a, b; scanf("%lld %lld %lld", &k, &a, &b);
if (k == 1) {
fenwick.update(a, b - arr[a]);
arr[a] = b;
} else {
printf("%lld\n", fenwick.query(b) - fenwick.query(a - 1));
}
}
}
'Algorithm > BOJ' 카테고리의 다른 글
백준[7626] 직사각형 (0) | 2021.09.01 |
---|---|
백준[3392] 화성지도 (0) | 2021.09.01 |
백준[17131] 여우가 정보섬에 올라온 이유 (0) | 2021.08.26 |
백준[2836] 수상 택시 (0) | 2021.08.25 |
백준[5419] 북서풍 (0) | 2021.08.20 |