algospot.com :: MORDOR
등산로 문제 정보 문제 모르도르 지방의 아름다운 경치를 한 눈에 볼 수 있는 명산 오로드루인에는 길기로 유명한 등산로가 있습니다. 이 등산로는 산등성이를 따라 오르락내리락하며 구성되어
www.algospot.com
세그먼트 트리라고 불리는 구간 트리를 활용하면 쉽게 풀 수 있는 문제였다.
구간의 최솟값을 저장하는 구간 트리는 알고리즘 문제해결 전략에 나와있는대로 구현하였고 구간의 최댓값을 구하기 위해 배열에 -1을 곱한 뒤 구간 트리를 한개 더 만들었다.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const int INTMAX = numeric_limits<int>::max();
void getMinus(int& a)
{
a *= -1;
}
class RMQ {
int n;
vector<int> rangeMin;
int init(const vector<int>& array, int left, int right, int node)
{
if (left == right)
return rangeMin[node] = array[left];
int mid = (left + right) / 2;
int leftMin = init(array, left, mid, node * 2);
int rightMin = init(array, mid + 1, right, node * 2 + 1);
return rangeMin[node] = min(leftMin, rightMin);
}
int query(int left, int right, int node, int nodeLeft, int nodeRight)
{
if (right < nodeLeft || nodeRight < left) return INTMAX;
if (left <= nodeLeft && nodeRight <= right) return rangeMin[node];
int mid = (nodeLeft + nodeRight) / 2;
return min(query(left, right, node * 2, nodeLeft, mid),
query(left, right, node * 2 + 1, mid + 1, nodeRight));
}
int update(int index, int newValue, int node, int nodeLeft, int nodeRight)
{
if (index < nodeLeft || nodeRight < index) return rangeMin[node];
if (nodeLeft == nodeRight) return rangeMin[node] = newValue;
int mid = (nodeLeft + nodeRight) / 2;
return rangeMin[node] = min(update(index, newValue, node * 2, nodeLeft, mid),
update(index, newValue, node * 2 + 1, mid + 1, nodeRight));
}
public:
RMQ(const vector<int>& array)
{
n = array.size();
rangeMin.resize(n * 4);
init(array, 0, n - 1, 1);
}
int query(int left, int right)
{
return query(left, right, 1, 0, n - 1);
}
int update(int index, int newValue)
{
return update(index, newValue, 1, 0, n - 1);
}
};
int main(void)
{
cin.tie(0);
ios_base::sync_with_stdio(0);
int tc;
cin >> tc;
while (tc--)
{
int N, Q;
cin >> N >> Q;
vector<int> board(N);
for (int i = 0; i < N; i++)
cin >> board[i];
RMQ boardMin(board);
for_each(board.begin(), board.end(), getMinus);
RMQ boardMax(board);
for (int i = 0; i < Q; i++)
{
int first, last;
cin >> first >> last;
cout << -boardMax.query(first, last) - boardMin.query(first, last) << endl;
}
}
}
알고리즘 200일 프로젝트 - 143 day
'알고리즘 > algospot' 카테고리의 다른 글
알고스팟: 안녕히, 그리고 물고기는 고마웠어요! (ID: SOLONG) (0) | 2020.08.31 |
---|---|
알고스팟: 너드인가, 너드가 아닌가? 2 (ID: NERD2) (0) | 2020.08.29 |
알고스팟: Jaeha’s Safe (ID: JAEHASAFE) (0) | 2020.08.25 |
알고스팟: 팰린드롬 만들기 (ID: PALINDROMIZE) (0) | 2020.08.25 |
알고스팟: 외계 신호 분석 (ID: ITES) (0) | 2020.08.23 |