백준 14428번, 수열과 쿼리 16
2020. 10. 1. 20:04ㆍProblem Solving/백준
문제
풀이
전형적인 세그먼트 트리를 구현하는 문제입니다.
left ~ right의 대푯값을 left ~ right에서 가장 작은 값의 인덱스로 놓아주고 갱신해주면 됩니다.
소스코드
#include <bits/stdc++.h>
using namespace std;
int arr[100001], seg[400001];
int init(int node, int start, int end) {
if (start == end) return seg[node] = start;
int mid = start + end >> 1;
int a = init(node * 2, start, mid), b = init(node * 2 + 1, mid + 1, end);
if (arr[a] == arr[b]) return seg[node] = min(a, b);
if (arr[a] > arr[b]) swap(a, b);
return seg[node] = a;
}
int query(int node, int start, int end, int left, int right) {
if (left <= start && end <= right) return seg[node];
if (left > end || right < start) return 0;
int mid = start + end >> 1;
int a = query(node * 2, start, mid, left, right), b = query(node * 2 + 1, mid + 1, end, left, right);
if (arr[a] == arr[b]) return min(a, b);
if (arr[a] > arr[b]) return b;
else return a;
}
int update(int node, int start, int end, int index) {
if (!(start <= index && index <= end)) return seg[node];
if (start == end) return index;
int mid = start + end >> 1;
int a = update(node * 2, start, mid, index), b = update(node * 2 + 1, mid + 1, end, index);
if (arr[a] == arr[b]) return seg[node] = min(a, b);
if (arr[a] > arr[b]) swap(a, b);
return seg[node] = a;
}
int main() {
cin.tie(0)->sync_with_stdio(0);
cout.tie(0);
arr[0] = 1e9 + 1;
int n; cin >> n;
for (int i = 1; i <= n; i++) cin >> arr[i];
init(1, 1, n);
int m; cin >> m;
while (m--) {
int a, b, c; cin >> a >> b >> c;
if (a == 1) { //update
arr[b] = c;
update(1, 1, n, b);
} else {
cout << query(1, 1, n, b, c) << "\n";
}
}
}
'Problem Solving > 백준' 카테고리의 다른 글
백준 1396번 (병렬 이분 탐색/PBS), 크루스칼의 공 (0) | 2020.10.03 |
---|---|
백준 6549번, 히스토그램에서 가장 큰 직사각형 (2) | 2020.10.02 |
백준 9997, 폰트 풀이 (0) | 2020.09.30 |
백준 14462, 소가 길을 건너간 이유 8 (0) | 2020.09.29 |
백준 1806번, 부분합 풀이 (0) | 2020.09.28 |