[백준] 2042: 구간 합 구하기 - JS (펜윅트리(BIT))
Algorithm 2023. 12. 7.
목 차
- 문제
- 접근 방식
- 풀이
문제
접근 방식
펜윅 트리는 구간 합을 구하는 것에 특화되어 있는 자료구조 이다.
펜윅 트리를 구성하는 메서드는 update 와 sum 메서드 이다.
update
// x: 업데이트 하는 인덱스, diff: 원래 값과 바뀐 값의 차이
- 인자: x, diff
- 조건: x <= N
- 동작: 인자로 들어온 x 에서 x & -x 를 더해주면 해당 인덱스가 영향을 주는 다음 인덱스를 찾아갈 수 있다.
sum
- 인자: x
- 조건: x > 0
- 동작: 인자로 들어온 x 에서 x & -x 를 빼주고 반복하면 1 부터 x 까지의 합을 구할 수 있다.
구간 합은 sum(b) - sum(a - 1) 을 해주면 구할 수 있다.
세그먼트 트리 보다는 구현이 쉬웠는데 범용성이 아쉽다. 구간 합 문제에서 편하게 사용할 수 있을 것 같다.
펜윅 트리를 구현하며 배운 것들
펜윅 트리를 위한 글에서 캡쳐하였다.
풀이
class FenwickTree {
// N: 요소 개수
constructor(N){
this.N = N;
this.tree = new BigInt64Array(this.N+1).fill(0n)
}
// index: 변경 된 인덱스, diff: 원래 값과 현재 값의 차이
update(index, diff){
while(index <= this.N){
this.tree[index] += BigInt(diff);
index += index & -index;
}
}
// sum 메서드: 1부터 index 까지의 합을 구하고 반환함
sum(index){
let result = 0n;
while(index > 0){
result += this.tree[index];
index -= index & -index;
}
return result
}
}
let input = require('fs').readFileSync( '/dev/stdin' ).toString().trim().split('\n');
const [N, M, K] = input[0].split(" ").map(Number);
const arr = new BigInt64Array(N + 1);
// 입력값
for(let i = 1; i <= N; i++){
arr[i] = BigInt(input[i]);
}
const ft = new FenwickTree(N)
// 초기화(initializing)
for(let i = 1; i <= N; i++){
ft.update(i, arr[i])
}
let answer = "";
for(let i = N + 1; i < N+M+K+1; i++){
const [a, b, c] = input[i].split(" ");
if(Number(a) == 1){
const diff = BigInt(c) - arr[b]
arr[b] = BigInt(c)
ft.update(Number(b), diff)
} else {
answer += `${ft.sum(Number(c)) - ft.sum(Number(b) - 1)}\n`
}
}
console.log(answer)
'Algorithm' 카테고리의 다른 글
[알고리즘] 퀵 정렬 (Quick Sort) (0) | 2023.12.26 |
---|---|
[알고리즘] CounterClockWise(CCW) (0) | 2023.12.14 |
[백준] 2042: 구간 합 구하기 - JS (세그먼트 트리) (0) | 2023.12.07 |
[자료구조] 펜윅 트리 (Fenwick Tree) - Binary Indexed Tree (0) | 2023.12.06 |
[알고리즘] 위상 정렬 (Topology Sort) (0) | 2023.11.29 |