用deque实时维护栈的情况。
数加入栈顶部,删掉栈顶部的数,相当于加入一个数,删掉最早出现的数,每次求最大值,这个直接记录一下就好了。
数加入栈底部,删掉栈顶部的数,相当于加入一个数,删掉最晚出现的数,每次求最大值,这个可以用单调队列。
两种数分别处理即可,被两个细节搞的调了好久T T
#include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<deque> #define MOD(x) ((x)>=modd?(x)-modd:(x)) using namespace std; const int maxn=10000010, modd=1e9+7; deque<int>ds; int n, A, B, C, a, b, mod, tott, ans; int x[maxn], q[maxn], ty[maxn], mx[maxn]; int main() { scanf("%d%d%d%d%d%d%d%d", &n, &A, &B, &C, &x[0], &a, &b, &mod); int l=1, r=0; for(int i=1;i<=n;i++) { x[i]=(1ll*x[i-1]*a+b)%mod; if(x[i]%(A+B+C)<A || ds.size()<=1) ty[i]=0; else if(x[i]%(A+B+C)<A+B) ty[i]=1; else if(A+B<=x[i]%(A+B+C)) ty[i]=2; if(!ty[i]) ds.push_front(i), ++tott, mx[tott]=max(mx[tott-1], x[i]); else if(ty[i]==1) { ds.push_back(i); while(l<=r && x[q[r]]<=x[i]) r--; q[++r]=i; } else { int delta=ds.front(); ds.pop_front(); if(ty[delta]) {if(q[l]==delta) l++;} else --tott; } ans+=max(mx[tott], q[l]?x[q[l]]:0); ans=MOD(ans); } printf("%d ", ans); }