Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 디자인 패턴
- 싱글턴
- 빌더
- 동적 데커레이터
- 컴포지트 패턴
- 팩터리 메서드
- 싱글톤 패턴
- 흐름식 빌더
- 추상 팩터리
- 싱글턴 패턴
- 프로토타입 패턴
- 프로토타입 중복처리
- 내부 팩터리
- 단순한 빌더
- 브릿지
- 컴포지트
- 빌더 패턴
- 프로토타입
- 데커레이터 패턴
- 컴포지트 빌더
- 팩터리 패턴
- 동적 데코레이터
- 데커레이터
- 브릿지 패턴
- 싱글톤
- 함수형 팩터리
- 팩터리
- 모던C++디자인패턴
- 디자인패턴
- 그루비 스타일 빌더
Archives
- Today
- Total
GGym's Practice Notes
백준 2042 : 구간 합 구하기 본문
세그먼트 트리 문제
세그먼트 트리에 대해서 알고 있다면 쉽게 풀 수 있는 문제다.
응용 없이 생성 - 갱신 - 합 과정 만을 사용한다.
#include<cstdio> // 2042_구간합구하기 [세그먼트트리]
#include<vector>
#include<cmath>
using namespace std;
#define max(x,y) x>y?x:y
int N, M, K;
// 세그먼트 트리
// - 생성 과정
long long init(
vector<long long> &a,
vector<long long> &tree,
int node, int start, int end
){
// 리프 노드일 경우
if(start == end)
return tree[node] = a[start];
// 가지 뻗기
else{
int mid = (start + end)/2;
return tree[node] =
init(a, tree, node*2+1, start, mid) +
init(a, tree, node*2+2, mid + 1, end);
}
}
// - 갱신 과정
void update(vector<long long> &tree, int node, int start, int end, int index, long long diff)
{
// 바꾸고자 하는 인덱스 검사
if (!(start <= index && index <= end))
return;
// 인덱스에 차이값 더하기
tree[node] += diff;
// 가지 뻗기
if(start != end)
{
int mid = (start + end) / 2;
update(tree, node * 2 + 1, start, mid, index, diff);
update(tree, node * 2 + 2, mid + 1, end, index, diff);
}
}
// - 합 과정
long long sum(
vector<long long> &tree,
int node, int start, int end, int left, int right
){
// [left, right] 와 [start, end] 가 전혀 겹치지 않는 경우
if(left > end || right < start)
return 0;
// [left, right] 와 [start, end] 가 서로 범위에 있을 경우
else if (left <= start && end <= right)
return tree[node];
// [left, right] 와 [start, end] 가 일부 겹치는 경우
else{
int mid = (start+end)/2;
return sum(tree, node * 2 + 1, start, mid, left, right) +
sum(tree, node * 2 + 2, mid+1, end, left, right);
}
}
int main(){
vector<long long> A, T;
scanf("%d %d %d", &N, &M, &K);
for(int i=1; i<=N; i++){
long long input;
scanf("%lld", &input);
A.push_back(input);
}
int h = (int)ceil(log2(N));
int treesize = (1 << (h+1));
T.assign(treesize, 0);
init(A, T, 0, 0, N-1);
for(int i=0; i<M+K; i++){
int a, b;
long long int c;
scanf("%d %d %lld", &a, &b, &c);
if(a == 1){
update(T, 0, 0, N-1, b-1, c - A[b-1]);
A[b-1] = c;
}
else if (a == 2)
printf("%lld\n", sum(T, 0, 0, N-1, b-1, c-1));
}
}
'Algorithm' 카테고리의 다른 글
백준 9935 : 문자열 폭발 (0) | 2021.04.28 |
---|---|
백준 1062 : 가르침 (0) | 2021.04.28 |
백준 1167 : 트리의 지름 (0) | 2021.04.20 |
프로그래머스 Level2_ 수식 최대화 (C++) (0) | 2020.10.31 |
프로그래머스 Level2_ 프린터 (C++) (0) | 2020.10.31 |