6549次ヒストグラムで最大の長方形(C++)
19149 ワード
https://www.acmicpc.net/problem/6549
これは,セグメントツリー資料構造を用いて解く問題である.
Segment Treeは、ある範囲のデータの和を迅速かつ簡単に求めるデータ構造である.
問題を解決する方法は次のとおりです.セグメントツリーを最低高さとするインデックス基準. の全部分に対して最低高さのインデックスを求め,区間の幅を求める. indexの左、右の部分については、2番と同じ方法で繰り返してください.
これは,セグメントツリー資料構造を用いて解く問題である.
Segment Treeは、ある範囲のデータの和を迅速かつ簡単に求めるデータ構造である.
問題を解決する方法は次のとおりです.
#include <iostream>
#include <string>
#include <vector>
#include <cmath>
using namespace std;
int n;
// segment tree 초기화
void init(vector<long long>& tree, vector<long long>& v, int node, int start, int end) {
if (start == end) tree[node] = start;
else {
int mid = (start + end) / 2;
init(tree, v, 2 * node, start, mid);
init(tree, v, 2 * node + 1, mid + 1, end);
if (v[tree[2 * node]] < v[tree[2 * node + 1]]) tree[node] = tree[2 * node];
else tree[node] = tree[2 * node + 1];
}
}
// 가장 작은 높이의 index 반환
int query(vector<long long>& tree, vector<long long>& v, int node, int start, int end, int left, int right) {
if (left <= start && end <= right) return tree[node];
else if (right < start || end < left) return -1;
int mid = (start + end) / 2;
int l = query(tree, v, 2 * node, start, mid, left, right);
int r = query(tree, v, 2 * node + 1, mid + 1, end, left, right);
if (l == -1) return r;
else if (r == -1) return l;
else if (v[l] < v[r]) return l;
else return r;
}
// 재귀를 통한 구간 합 계산
long long get_max_area(vector<long long>& tree, vector<long long>& v, int start, int end) {
int idx = query(tree, v, 1, 1, n, start, end);
long long area = (end - start + 1) * v[idx];
if (idx > start) {
long long left = get_max_area(tree, v, start, idx - 1);
area = max(area, left);
}
if (idx < end) {
long long right = get_max_area(tree, v, idx + 1, end);
area = max(area, right);
}
return area;
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin >> n;
while (n != 0) {
vector<long long> v(n + 1);
for (int i = 1; i <= n; i++) {
cin >> v[i];
}
int height = (int)ceil(log2(n));
int tree_size = (1 << (height + 1));
vector<long long> tree(tree_size);
init(tree, v, 1, 1, n);
cout << get_max_area(tree, v, 1, n) << "\n";
cin >> n;
}
}
Reference
この問題について(6549次ヒストグラムで最大の長方形(C++)), 我々は、より多くの情報をここで見つけました https://velog.io/@khc41/6549번-히스토그램에서-가장-큰-직사각형-Cテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol