Algorithm/백준
[백준 알고리즘] 2042번: 구간 합 구하기 (JAVA)
에릭 Kim
2024. 2. 2. 09:16
반응형
https://www.acmicpc.net/problem/2042
2042번: 구간 합 구하기
첫째 줄에 수의 개수 N(1 ≤ N ≤ 1,000,000)과 M(1 ≤ M ≤ 10,000), K(1 ≤ K ≤ 10,000) 가 주어진다. M은 수의 변경이 일어나는 횟수이고, K는 구간의 합을 구하는 횟수이다. 그리고 둘째 줄부터 N+1번째 줄
www.acmicpc.net
소스코드
import java.util.*;
import java.io.*;
class Main {
static long[] arr;
static int a,b;
static long c;
public static class SegmentTree {
long[] tree;
int treeSize;
public SegmentTree(int arrSize) {
int h = (int) Math.ceil(Math.log(arrSize) / Math.log(2));
this.treeSize = (int) Math.pow(2,h+1);
tree = new long[treeSize];
}
public long init(long[] tree, int node, int start, int end) {
if (start == end) return tree[node] = arr[start];
int mid = (start+end) / 2;
return tree[node] = init(tree,node*2,start,mid)
+ init(tree,node*2+1,mid+1,end);
}
public void update(long[] tree, int node, int start, int end, int idx, long diff) {
if (idx < start || idx > end) return;
tree[node] += diff;
int mid = (start+end) / 2;
if (start != end) {
update(tree,node*2,start,mid,idx,diff);
update(tree,node*2+1,mid+1,end,idx,diff);
}
}
public long sum(long[] tree, int node, int start, int end, int left, int right) {
if (left > end || right < start) return 0;
if (left <= start && end <= right) return tree[node];
int mid = (start+end) / 2;
return sum(tree,node*2,start,mid,left,right)
+ sum(tree,node*2+1,mid+1,end,left,right);
}
}
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine()," ");
StringBuilder sb = new StringBuilder();
int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());
int k = Integer.parseInt(st.nextToken());
arr = new long[N+1];
for (int i=1; i<=N;i++) {
arr[i] = Long.parseLong(br.readLine());
}
SegmentTree sgTree = new SegmentTree(N);
sgTree.init(sgTree.tree,1,1,N);
for (int i=0; i< M+k;i++) {
st = new StringTokenizer(br.readLine());
a = Integer.parseInt(st.nextToken());
b = Integer.parseInt(st.nextToken());
c = Long.parseLong(st.nextToken());
if (a == 1) {
sgTree.update(sgTree.tree,1,1,N,b,c-arr[b]);
arr[b] = c;
}
else {
sb.append(sgTree.sum(sgTree.tree,1,1,N,b,(int) c)).append("\n");
}
}
System.out.println(sb);
}
}
풀이
★세그먼트 트리를 사용하는 아주 기본적인 문제입니다 ! 구간의 합을 누적합이나 반복문으로 풀게 되면 시간초과가 발생하게 되고, 세그먼트 트리라는 알고리즘을 사용하여 풀어야 합니다 :)
★ 세그먼트 트리 참고
https://hongjw1938.tistory.com/20
자료구조 - 세그먼트 트리(Segment Tree)
1. 세그먼트 트리(Segment Tree, 구간 트리)란? 특정 구간 내 연산(쿼리)에 대해 빠르게 응답하기 위해 만들어진 자료구조이다. 예를 들어 크기가 N=100인 int배열 arr이 있다면 1~100의 인덱스 내 숫자들
hongjw1938.tistory.com
반응형