Loading

HDU 1506 / SP1805 Largest Rectangle in a Histogram

题目

image

思路

我们要充分利用笛卡尔树的性质:

  1. 一颗子树内的点表现在数组上都是连续的;
  2. 一颗子树内的点的大小都大于等于子树跟的数值大小。

所以我们建出笛卡尔树,用 dfs 求出以每个点为子树的子树大小 \(sz_i\),那么对于这个高度 \(h_i\) 来说,其子节点的高度比它大,所以可以拓展开来,面积为 \(sz_i \cdot h_i\),最后取个 max 即可。

代码

// hdu 1506

#include <bits/stdc++.h>

using namespace std;
using i64 = long long;

const int N = 100010;

int n, a[N];
int lc[N], rc[N];
int stk[N], top;
int sz[N];

void dfs(int u) {
    sz[u] = 1;
    if (lc[u]) dfs(lc[u]);
    if (rc[u]) dfs(rc[u]);
    sz[u] += sz[lc[u]] + sz[rc[u]];
}

void solve() {
    fill(lc + 1, lc + n + 1, 0);
    fill(rc + 1, rc + n + 1, 0);
    top = 0;

    for (int i = 1; i <= n; i++) cin >> a[i];

    for (int i = 1; i <= n; i++) {
        int k = top;
        while (k && a[stk[k]] > a[i]) k--;
        if (k) rc[stk[k]] = i;
        if (k < top) lc[i] = stk[k + 1];
        stk[++k] = i;
        top = k;
    }
    dfs(stk[1]);
    i64 ans = 0;
    for (int i = 1; i <= n; i++) ans = max(ans, 1ll * sz[i] * a[i]);
    cout << ans << '\n';
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    while (cin >> n && n) solve();
    return 0;
}
posted @ 2024-08-23 10:56  SunnyYuan  阅读(3)  评论(0编辑  收藏  举报