• 单调栈总结


    新做了两道题居然和之前套路是一样的,就不重复了

    有趣的是

    while (!s.empty() && a[s.top()] < a[i]) 这个循环里,< 和 <=这两个都可以,模拟了一下发现,当你想把一个数字入栈的时候,如果前面一个数字和当前这个一样,虽然当前这个数字不能向前搜到最深,但是前一个数字和这个是一样的,所以一定有一个能向前找到最深的和当前这个数字相同的数字。

    POJ-2796

    #include <cstdio>
    #include <algorithm>
    #include <stack>
    using namespace std;
    const int N = 100010;
    int a[N];
    typedef long long ll;
    ll pre[N];
    stack < int > s;
    int main() {
        int n, l = 1, r = 1;
        scanf("%d", &n);
        for (int i = 1; i <= n; i++) {
            scanf("%d", &a[i]);
            pre[i] = pre[i - 1] + a[i];
        }
        ll ans = 0;
        for (int i = 1; i <= n; i++) {
            int top = i;
            while (!s.empty() && a[s.top()] > a[i]) {
                top = s.top();
                if (ans < 1ll * (pre[i - 1] - pre[top - 1]) * a[top]) {
                    ans = 1ll * (pre[i - 1] - pre[top - 1]) * a[top];
                    l = s.top(); r = i - 1;
                }
                s.pop();
            }
            a[top] = a[i];
            s.push(top);
        }
        while (!s.empty()) {
            if (ans < 1ll * (pre[n] - pre[s.top() - 1]) * a[s.top()]) {
                ans = 1ll * (pre[n] - pre[s.top() - 1]) * a[s.top()];
                l = s.top(); r = n;
            }
            s.pop();
        }
        printf("%lld
    %d %d", ans, l, r);
        return 0;
    }

    POJ-2559

    #include <cstdio>
    #include <algorithm>
    #include <stack>
    using namespace std;
    stack < int > s;
    typedef long long ll;
    const int N = 100010;
    ll h[N];
    int main() {
        int n;
        while (~scanf("%d", &n)) {
            if (n == 0)
                break;
            ll ans = 0;
            for (int i = 0; i < n; i++) {
                scanf("%lld", &h[i]);
                int top = i;
                while (!s.empty() && h[s.top()] > h[i]) {
                    top = s.top(); s.pop();
                    ans = max(ans, 1ll * (i - top) * h[top]);
                }
                h[top] = h[i];
                s.push(top);
            }
            while (!s.empty()) {
                ans = max(ans, 1ll * (n - s.top()) * h[s.top()]);
                s.pop();
            }
            printf("%lld
    ", ans);
        }
        return 0;
    }

    笛卡尔树就放到RMQ的时候一起学吧

  • 相关阅读:
    document.form.action一个页面多个action,表单分向提交
    jdk多个版本切换
    (已解决)No result defined for action and result input
    struts2中action中的void方法
    时间格式yy-MM-dd HH:mm:ss
    Spring在Action中不用注入实体类
    css背景色的线性渐变
    ElasticSearch入门
    Git命令进阶
    websocket入门代码
  • 原文地址:https://www.cnblogs.com/cminus/p/12464875.html
Copyright © 2020-2023  润新知