반응형
https://www.acmicpc.net/problem/17408
17408번: 수열과 쿼리 24
길이가 N인 수열 A1, A2, ..., AN이 주어진다. 이때, 다음 쿼리를 수행하는 프로그램을 작성하시오 1 i v: Ai를 v로 바꾼다. (1 ≤ i ≤ N, 1 ≤ v ≤ 109) 2 l r: l ≤ i < j ≤ r을 만족하는 모든 Ai + Aj 중에서
www.acmicpc.net
[ 문제풀이 ]
이 문제를 풀기 전에 다음 글을 먼저 읽고 오시는 것을 추천드립니다.
https://rudalsd.tistory.com/51
[ 자료구조 ] 세그먼트 트리 (Segment Tree)
1. 세그먼트 트리 (Segment Tree) 먼저, 세그먼트 트리가 무엇인지 알아봅시다! 세그먼트 트리는 구간 합을 저장하기 위한 트리입니다. 예를 들어 size가 5인 배열이 있다고 생각해봅시다. int arr [5] = {1
rudalsd.tistory.com
1. 세그먼트 트리의 노드에 구간의 최댓값과 인덱스를 저장해 줍니다.
2. l부터 r까지의 인덱스 중 최댓값의 인덱스를 저장하고, l 부터 인덱스까지 와 인덱스 + 1 부터 r 까지의 값과 l부터 인덱스 -1 까지와 인덱스부터 r까지의 합 중 더 큰 값을 출력합니다.
[ 소스코드 ]
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | #include<iostream> using namespace std; int N, M; pair<int,int> segTree[262222]; int arr[100001]; void makeTree(int node, int s, int e) { if (s == e) { segTree[node] = { arr[s], s}; return; } int m = (s + e) / 2; makeTree(node * 2, s, m); makeTree(node * 2 + 1, m + 1, e); if (segTree[node*2].first > segTree[node*2+1].first) { segTree[node] = segTree[node * 2]; } else { segTree[node] = segTree[node * 2 + 1]; } } void updateTree(int node, int s, int e, int idx, int v) { if (idx < s || e < idx) return; if (s == e) { segTree[node].first = v; return; } int m = (s + e) / 2; updateTree(node * 2, s, m, idx, v); updateTree(node * 2 + 1, m + 1, e, idx, v); if (segTree[node * 2].first > segTree[node * 2 + 1].first) { segTree[node] = segTree[node * 2]; } else { segTree[node] = segTree[node * 2 + 1]; } } pair<int,int> getTree(int node, int s, int e, int sidx, int eidx) { if (e < sidx || s > eidx) return { 0,0 }; if (sidx <= s && e <= eidx) return segTree[node]; int m = (s + e) / 2; pair<int, int> left = getTree(node * 2, s, m, sidx, eidx); pair<int, int> right = getTree(node * 2 + 1, m + 1, e, sidx, eidx); if (left.first > right.first) { return left; } else { return right; } } int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); cin >> N; for (int i = 1; i <= N; i++) { cin >> arr[i]; } makeTree(1, 1, N); cin >> M; for (int t = 0; t < M; t++) { int cmd; cin >> cmd; if (cmd == 1) { int i, v; cin >> i >> v; updateTree(1, 1, N, i, v); } else { int l, r; cin >> l >> r; int idx = getTree(1, 1, N, l, r).second; int ans = max(getTree(1, 1, N, l, idx).first + getTree(1, 1, N, idx + 1, r).first, getTree(1, 1, N, l, idx - 1).first + getTree(1, 1, N, idx, r).first); cout << ans << '\n'; } } } | cs |
반응형
'백준' 카테고리의 다른 글
[ 백준 ] 2465번 - 줄 세우기 (C++) (0) | 2023.08.06 |
---|---|
[ 백준 ] 5012번 - 불만 정렬 (C++) (0) | 2023.08.05 |
[ 백준 ] 14459번 - 소가 길을 건너간 이유 11 (C++) (0) | 2023.08.03 |
[ 백준 ] 15967번 - 에바쿰 (C++) (0) | 2023.08.02 |
[ 백준 ] 16978번 - 수열과 쿼리 22 (C++) (0) | 2023.08.01 |