poj 2796 Feel Good 单调栈题解

1.C name rp 名字为name人品为rp的人排到队尾
2.G 队首的人出队
3.Q 询问当前队列中rp最高的

要求实现这三个操作。

单调栈模板题
系统学习单调栈和单调队列戳:单调队列和单调栈详解
https://endlesslethe.com/monotone-queue-and-stack-tutorial.html

#include <bits/stdc++.h>
using namespace::std;

typedef long long ll;
const ll MAXN = 100000+50;
ll ms[MAXN], r;
ll L[MAXN], R[MAXN];
ll n, pos, maxNum, x[MAXN];
ll sum[MAXN];

int main() {
    ios_base::sync_with_stdio(0);cin.tie(0);
    #ifdef LOCAL
        //freopen("in.txt","r",stdin);
        //freopen("out.txt","w",stdout);
    #endif
    while (scanf("%d", &n) == 1) {
        r = pos = 0;
        maxNum = -1;
        for (ll i = 1; i <= n; i++) {
            scanf("%I64d", &x[i]);
            sum[i] = x[i] + sum[i-1];
        }
        for (ll i = 1; i <= n; i++) {
            while (r != 0 && x[ms[r]] >= x[i]) {
                R[ms[r]] = i - ms[r] -1;
                r--;
            }
            L[i] = i - ms[r] - 1;
            ms[++r] = i;
        }
        while (r) {
            R[ms[r]] = n - ms[r];
            r--;
        }
        for (ll i = 1; i <= n; i++) {
            int l = i - L[i], r = i+R[i];
            if ((sum[r] - sum[l-1]) * x[i] > maxNum) {
                maxNum = (sum[r] - sum[l-1]) * x[i];
                pos = i;
            }
        }
        printf("%I64d\n", maxNum);
        printf("%I64d %I64d\n", pos - L[pos], pos + R[pos]);
    }
    return 0;
}
点赞