51nod 1952 栈(单调队列)

  用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);
}
View Code
原文地址:https://www.cnblogs.com/Sakits/p/8032482.html