안녕하세요. 개발자 움탱입니다.
이 기사는 알고리즘을 공부하면서 공부를 추적하기 위한 것입니다.
그래서 설명마다 일기장으로 편하게 쓰려고 하고 짧은 언어 형식으로 쓰려고 합니다.
그리고 더 좋은 시각이 있으시거나 잘 모르시는 부분이 있으시면 알려주시면 정말 감사하겠습니다.
좋은 하루 보내세요 🙂
문제가 있는 링크
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
문제 설명
구간의 합을 구하는 문제는 단순히 문제에 주어진 구간의 합을 계산하는 문제입니다.
그러나 평균 숫자가 변경되고 그에 따라 새 합계가 계산됩니다.
논평
나는 단지 간격의 합을 찾을 것이라고 생각했고, 간격을 얻을 때마다 반복문을 뒤집어 답을 계산할 것이라고 생각했습니다. 루프를 실행하면 최대 자릿수가 2^63이므로 시간이 초과됩니다.날수있다
이 문제는 일반적인 세그먼트 트리 문제입니다.오전.
우선 세그먼트 트리를 공부하고 풀어서 연습하는 것이 좋은 작업입니다.
아래는 백준의 세그먼트 트리에 대해 보도한 기사입니다.
https://www.acmicpc.net/blog/view/9
세그먼트 트리
기사가 업데이트되었습니다. https://book.acmicpc.net/ds/segment-tree 문제 배열 A가 있고 다음 두 작업을 수행해야 하는 문제를 생각해 봅시다. 구간 l과 r이 주어지면(l ≤ r), A(l) + A(l+1) + ..
www.acmicpc.net
암호
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
public static void main(String() args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
int N = Integer.parseInt(st.nextToken()); // 수의 개수
int M = Integer.parseInt(st.nextToken()); // 수의 변경이 일어나는 횟수
int K = Integer.parseInt(st.nextToken()); // 구간의 합을 구하는 횟수
long() arr = new long(N + 1);
for (int i = 1; i <= N; i++) {
arr(i) = Long.parseLong(br.readLine());
}
SegmentTree segment = new SegmentTree(arr);
segment.init(1, 1, N);
for (int i = 0; i < M + K; i++) {
st = new StringTokenizer(br.readLine(), " ");
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
long c = Long.parseLong(st.nextToken());
if (a == 1) {
segment.update(1, 1, N, b, c - segment.getArr()(b));
segment.updateArr(b, c);
} else {
System.out.println(segment.sum(1, 1, N, b, (int)c));
}
}
br.close();
}
}
class SegmentTree {
private long() tree;
private long() arr;
public SegmentTree(long() arr) {
int height = (int)Math.ceil(Math.log(arr.length - 1) / Math.log(2));
tree = new long((int)Math.pow(2, height + 1));
this.arr = arr;
}
public long init(int node, int start, int end) {
if (start == end) {
return this.tree(node) = this.arr(start);
}
return this.tree(node) = init(node * 2, start, (start + end) / 2) +
init(node * 2 + 1, (start + end) / 2 + 1, end);
}
public void update(int node, int start, int end, int idx, long diff) {
if (idx < start || end < idx) {
return;
}
this.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);
}
}
public 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 this.tree(node);
}
return sum(node * 2, start, (start + end) / 2, left, right) +
sum(node * 2 + 1, (start + end) / 2 + 1, end, left, right);
}
public long() getArr() {
return this.arr;
}
public void updateArr(int idx, long value) {
this.arr(idx) = value;
}
}

