51nod 1952 栈

题目链接戳这

如果只是从尾端插入,那么问题就是基础的:求取栈内最大值的问题,这用单调栈解决即可。

但是前端也能插入,一般的单调栈已经不能满足。那么想象,如果在前端插入一个小值,相当于在栈底多加一个值罢了。但若加入一个大值呢?则需要把栈底的元素从下面逐个取出来,相当于这些比当前要插入的值“不曾存在过”,再从前端插入当前值。

由于涉及从前端插入,那么用双端队列实现双端的单调栈即可。

#include <stdio.h>
#include <deque>
using namespace std;

#define ll long long
#define pb push_back
#define pf push_front

const ll maxN=1e7+5;
ll n, A, B, C, x, a, b, MOD;
ll M = 1e9 + 7, ans;
deque<ll> dq, stk;

int main() {
#ifndef ONLINE_JUDGE
    freopen("data.in", "r", stdin);
#endif
    scanf("%lld%lld%lld%lld %lld%lld%lld%lld",
            &n, &A, &B, &C, &x, &a, &b, &MOD);
    ans = 0;
    for (ll i = 1; i <= n; ++i) {
        x = (x * a + b) % MOD;
        ll xabc = x % (A + B + C);
        if (xabc < A || dq.size() <= 1) {
            dq.pb(x);
            if (stk.empty() || x >= stk.back())
                stk.push_back(x);
            ans = (ans + stk.back()) % M;
        } else if (A <= xabc && xabc < A + B){
            dq.pf(x);
            while (stk.size() && x > stk.front())
                stk.pop_front();
            stk.push_front(x);
            ans = (ans + stk.back()) % M;
        } else if (A + B <= xabc) {
            ll out = dq.back();
            dq.pop_back();
            if (out == stk.back())
                stk.pop_back();
            ans = (ans + stk.back()) % M;
        }
    }
    printf("%lld
", ans);
    return 0;
}
原文地址:https://www.cnblogs.com/Rosebud/p/9529080.html