BOJ 백준 6549 : 히스토그램에서 가장 큰 직사각형
Updated:
시작하면서
이번 문제는 세그먼트 트리(Segment Tree) 문제이다.
문제 이해
이번 문제는 잘 설명되어 있는 링크로 대체한다.
해결
#include <iostream>
#include <vector>
#include <math.h>
using namespace std;
void InitSegmentTree(vector<int>& tree, vector<int>& ary, int node, int start, int end)
{
if (start == end)
{
tree[node] = start;
return;
}
int mid = (start + end) * 0.5f;
InitSegmentTree(tree, ary, node * 2, start, mid);
InitSegmentTree(tree, ary, node * 2 + 1, mid + 1, end);
if (ary[tree[node * 2]] <= ary[tree[node * 2 + 1]])
{
tree[node] = tree[node * 2];
}
else
{
tree[node] = tree[node * 2 + 1];
}
}
int QuerySegmentTree(vector<int>& tree, vector<int>& ary, int node, int start, int end, int left, int right)
{
if (left > end || right < start)
return -1;
if (left <= start && end <= right)
return tree[node];
int mid = (start + end) * 0.5f;
int l = QuerySegmentTree(tree, ary, node * 2, start, mid, left, right);
int r = QuerySegmentTree(tree, ary, node * 2 + 1, mid + 1, end, left, right);
if (l == -1)
{
return r;
}
else if (r == -1)
{
return l;
}
else if (ary[l] <= ary[r])
{
return l;
}
else
{
return r;
}
}
long long GetLargestRectangle(vector<int>& tree, vector<int>& ary, int start, int end)
{
int size = ary.size() - 1;
int query = QuerySegmentTree(tree, ary, 1, 0, size, start, end);
long long result = ((long long)end - start + 1) * ary[query];
if (start <= query - 1)
{
long long cmp = GetLargestRectangle(tree, ary, start, query - 1);
result = max(result, cmp);
}
if (query + 1 <= end)
{
long long cmp = GetLargestRectangle(tree, ary, query + 1, end);
result = max(result, cmp);
}
return result;
}
int main()
{
// sync off
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
// sync off
int n;
vector<int> heights;
vector<int> tree;
while (true)
{
cin >> n;
if (n == 0)
break;
int height = (int)(ceil(log2(n)) + 1e-9);
heights.resize(n);
tree.resize(1 << (height + 1));
for (int i = 0; i < n; i++)
{
cin >> heights[i];
}
InitSegmentTree(tree, heights, 1, 0, n - 1);
cout << GetLargestRectangle(tree, heights, 0, n - 1) << "\n";
}
return 0;
}
Leave a comment