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\n", ans); return 0; }