문제는 간단합니다.
!
= 실력이 늘었습니다.
다만 타이밍이 맞지 않아서 원하는 대로 헤쳐나갈 수 없을 뿐입니다.
실제로 간격 합이나 차이와 같은 문제에 부딪히면 주로 Prefix Sum으로 문제를 해결하려고 합니다.
BTW, PrefixSum은 특정 간격에 걸쳐 합계를 계산할 때 분명히 O(1)의 이점이 있지만
단점은 중간 값을 수정하는 데 O(N) 시간이 걸린다는 것입니다.
따라서 이 문제를 해결하면 시간이 초과되는 경우가 있습니다.
여기서 배워야 할 것은 선분 트리입니다.
세그먼트 트리를 업데이트하면 시간을 O(NlogN)로 줄일 수 있습니다.
나는 모른다?한 번 기억
import java.util.*;
import java.io.*;
class SegmentTree {
long () tree;
int treeSize;
SegmentTree(int n) {
int h = (int)Math.ceil(Math.log(n)/Math.log(2));
this.treeSize = (int)Math.pow(2, h+1);
tree = new long(treeSize);
}
long init(long () arr, int node, int start, int end) {
// 리프노드 인거
if(start == end) {
return tree(node) = arr(start);
}
return tree(node) = init(arr, node*2, start, (start+end)/2)
+ init(arr,node*2+1, (start+end)/2+1, end);
}
void update(int node, int start, int end, int idx, long diff) {
if(idx < start || end < idx) {
return;
}
tree(node) += diff;
if(start !
= end) {
update(node*2, start, (start+end)/2, idx, diff);
update(node*2+1, (start+end)/2+1, end, idx, diff);
}
}
long sum(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);
}
return sum(node*2, start, (start+end)/2, left, right) +
sum(node*2+1, (start+end)/2+1, end, left, right);
}
}
public class 세그먼트트리 {
public static void main(String() args) throws IOException{
// TODO Auto-generated method stub
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String () tmp = br.readLine().strip().split(" ");
int n = Integer.parseInt(tmp(0));
int times = Integer.parseInt(tmp(1))+Integer.parseInt(tmp(2));
long () arr = new long(n+1);
for(int i=1;i<=n;i++) {
arr(i) = Integer.parseInt(br.readLine().strip());
}
SegmentTree tree = new SegmentTree(n);
tree.init(arr, 1, 1, n);
for(int i=0;i<times;i++) {
tmp = br.readLine().strip().split(" ");
int type = Integer.parseInt(tmp(0).strip());
if(type == 1) {
int update_node = Integer.parseInt(tmp(1));
int update_num = Integer.parseInt(tmp(2));
long diff = update_num - arr(update_node);
tree.update(1, 1, n, update_node, diff);
} else {
int left = Integer.parseInt(tmp(1));
int right = Integer.parseInt(tmp(2));
long sum_value = tree.sum(1, 1, n, left, right);
System.out.println(sum_value);
}
}
}
}