-
반응형
https://www.acmicpc.net/problem/1306
1306번: 달려라 홍준
첫째 줄에는 뛰는 코스의 길이, 즉 칸수 N과 홍준이의 시야의 범위 M이 주어진다. 시야가 M이라고 하면 현재 위치에서 앞뒤로 M-1칸까지 광고판이 보이는 것이다. (1 ≤ M ≤ N ≤ 1,000,000) 두 번째
www.acmicpc.net
풀이
세그먼트 트리를 이용해서 범위별 최댓값을 저장해둔뒤, 현재 홍준이가 뛰는 위치가 i번째( 단 M<=i && i<= N-M+1) 라고 한다면, 세그먼트트리의 쿼리를 이용하여 i-M ~ i+M 범위중 최댓값을 구해서 출력하면된다.
시간복잡도
세그먼트트리 초기화에 O(logN), 각 쿼리마다 O(logN) 이므로, 총 O(NlogN)이 된다.
코드
#include <iostream> #include<vector> #include<cmath> using namespace std; typedef long long ll; class Seg { public: vector<int> arr; vector<ll> tree; Seg(int n) { arr.resize(n); int h = (int)ceil(log2(n)); int tree_size = (1 << (h + 1)); tree.resize(tree_size); } void input(int n) { for (int i = 0; i < n; i++) { cin >> arr[i]; } } int init(int node, int st, int end) { if (st == end) { return tree[node]=arr[st]; } int middle = (st + end) / 2; int left = init(node * 2, st, middle); int right = init(node * 2 + 1, middle + 1, end); return tree[node] = (left<right?right:left); } int query(int node, int st, int end, int l, int r) { if (r < st || end < l) { return -1; } if (l <= st && end <= r) { return tree[node]; } int middle = (st + end) / 2; int left = query(node * 2, st, middle, l, r); int right=query(node * 2 + 1, middle + 1, end, l, r); return (left < right ? right : left); } }; int main() { int n, m; cin >> n >> m; m--; Seg seg(n); seg.input(n); seg.init(1,0,n-1); for (int i = m; i < n - m; i++) { cout << seg.query(1, 0, n - 1, i - m, i + m) << " "; } return 0; }
반응형'문제풀이 > 백준oj' 카테고리의 다른 글
[백준OJ] 1916번 최소비용 구하기 (0) 2021.08.17 [백준OJ] 1275번 커피숍2 (0) 2021.08.16 [백준OJ] 20114번 미아 노트 (0) 2021.08.15 [백준OJ] 6987번 월드컵 (0) 2021.08.14 [백준OJ] 9019번 DSLR (0) 2021.08.13 댓글