티스토리 뷰
#include <stdio.h>
long long arr[100001] = {};
long long tree[100001] = {};
int n, q;
void update(int i, long long x) { //트리의 값을 수정합니다.
while(i <= n) {
tree[i] += x;
i += i&(-i);
}
}
long long sum(int i) { //구간합을 계산 후 반환합니다.
long long ans = 0;
while(i) {
ans += tree[i];
i -= i&(-i);
}
return ans;
}
int main(void) {
scanf("%d %d", &n, &q); ///n, q 입력
for(int i=1; i<=n; i++) { //n개의 요소들을 입력받습니다.
scanf("%lld", &arr[i]);
update(i, arr[i]);
}
while(q--) {
int x, y, a, b;
scanf("%d %d %d %d", &x, &y, &a, &b);
if(x > y) {
int tmp = x;
x = y;
y = tmp;
}
printf("%lld\n", sum(y)-sum(x-1)); //구간합을 출력합니다.
update(a, b-arr[a]); //트리의 값을 수정합니다.
arr[a] = b; //요소도 수정해 줍니다.
}
}
풀이 : Fenwick tree
구간합을 푸는 문제중에선
1. 단일 합, 구간 수정
2, 구간 합, 단일 수정
3, 구간 합, 구간 수정
으로 나눌 수 있으며
이 문제의 경우는, 구간합을 출력하고, 단일 수정을 하므로
segment tree로 풀 수 있으나, 이 중 Fenwick tree 을 사용하면, 빠르게 구간합과, 단일 수정을 할 수 있다.
update1
tree[1] = arr[1]
tree[2] = arr[1] + arr[2]
tree[3] = arr[3]
tree[4] = arr[1] + arr[2] + arr[3] + arr[4]
tree[5] = arr[5]
tree[6] = arr[5] + arr[6]
tree[7] = arr[7]
tree[8] = arr[1] + arr[2] + arr[3] + arr[4] + arr[5] + arr[6] + arr[7] + arr[8]
sum
sum(1) = tree[1]
sum(2) = tree[2] = arr[1] + arr[2]
sum(3) = tree[3] + tree[2] = arr[3] + arr[1] + arr[2]
sum(4) = tree[4] = arr[4] + tree[3] + tree[2] = arr[4] + arr[3] + arr[1] + arr[2]
sum(5) = tree[5] + tree[4] = arr[5] + arr[4] + arr[3] + arr[1] + arr[2]
sum(6) = tree[6] + tree[4] = arr[6] + arr[5] + arr[4] + arr[3] + arr[1] + arr[2]
sum(7) = tree[7] + tree[6] + tree[4] = arr[7] + arr[6] + arr[5] + arr[4] + arr[3] + arr[1] + arr[2]
sum(8) = tree[8] = tree[4] + tree[6] + tree[7] = arr[8] + arr[7] + arr[6] + arr[5] + arr[4] + arr[3] + arr[1] + arr[2]
Fenwick 트리로 구간합을 구할 수 있다!
과정
1. n, q을 입력받는다
2. n개의 요소를 입력받는다, 입력을 받을 때 마다 tree을 update한다. (tree배열의 모든 요소를 0으로 초기화 한다)
3. q만큼 query 처리 후 update을 반복 합니다.
3.1 x부터 y까지의 구간합을 출력해야하나, 만약 x>y라면 y부터 x까지의 구간합을 출력해야 합니다.
https://www.acmicpc.net/problem/1275
1275번: 커피숍2
첫째 줄에 수의 개수 N과 턴의 개수 Q가 주어진다.(1 ≤ N, Q ≤ 100,000) 둘째 줄에는 처음 배열에 들어가 있는 정수 N개가 주어진다. 세 번째 줄에서 Q+2번째 줄까지는 x y a b의 형식으로 x~y까지의 합
www.acmicpc.net
'c언어 > BAEKJOON' 카테고리의 다른 글
c언어 2357번 최솟값과 최댓값 (백준) (0) | 2023.04.20 |
---|---|
c언어 10868번 최솟값 (백준) (0) | 2023.04.20 |
c언어 4375번 1 (백준) (0) | 2023.04.15 |
c언어 16975번 수열과 쿼리 21 (백준) (0) | 2023.04.12 |
c언어 18436번 수열과 쿼리 37 (백준) (0) | 2023.04.12 |
- Total
- Today
- Yesterday
- C++
- DP
- 스택
- 1835
- 그리디
- BFS
- 1835번
- 기하학
- Segment Tree
- XOR
- 덱
- find
- Krustal
- PASCAL
- 누적 합
- 누적합
- C언어
- 백준
- 플로이드
- 그래프
- 정렬
- 브루트포스
- 최대공약수
- 오프라인 쿼리
- 최소 스패닝 트리
- Lazy Propagation
- DFS
- 세그먼트 트리
- union
- java
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |