zoukankan      html  css  js  c++  java
  • 【51Nod1952】栈-单调栈+单调队列

    测试地址:
    做法:本题需要用到单调栈+单调队列。
    我们可以用一些高级数据结构O(nlogn)简易地算出这个结果,但是看到数据范围,知道我们必须要找一个O(n)的做法。
    我们看既有插入又有删除的那一端,显然可以用一个单调栈来维护,单调栈内的元素从栈底到栈顶应该严格递增。
    那么另一端我们怎么处理呢?我们发现,只有当上面的单调栈取完时,我们会删掉对另一端来说是尾端的一个元素,而插入和删除不在一端的数据结构显然是队列,启发我们用单调队列来维护另一端,单调队列里的元素从队首到队尾应该递减,但不是严格递减。
    这样一来,求最大值时就将单调栈的栈顶和单调队列的队首比较一下即可,而删除一个元素时,首先删栈中的元素,当栈中没有元素时再删队列的队首。因为每个元素最多进队(栈)和出队(栈)一次,所以时间复杂度是O(n)的。
    以下是本人代码:

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const ll mod=1000000007;
    int n,top,h,t,q[10000010],st[10000010];
    int posq[10000010],posst[10000010],totq=0,totst=0,qhead=0;
    ll A,B,C,x0,a,b,MOD,ans=0;
    
    int main()
    {
        scanf("%d%lld%lld%lld%lld%lld%lld%lld",&n,&A,&B,&C,&x0,&a,&b,&MOD);
    
        ll x=x0;
        top=t=0;h=1;
        for(int i=1;i<=n;i++)
        {
            x=(x*a+b)%MOD;
            if (x%(A+B+C)<A||(totst+totq-qhead)<=1)
            {
                totst++;
                if (!top||st[top]<x)
                {
                    st[++top]=x;
                    posst[top]=totst;
                }
            }
            else if (x%(A+B+C)<A+B)
            {
                totq++;
                while(h<=t&&q[t]<x) t--;
                q[++t]=x;
                posq[t]=totq;
            }
            else
            {
                if (top)
                {
                    totst--;
                    while(top&&posst[top]>totst) top--;
                }
                else
                {
                    qhead++;
                    while(h<=t&&posq[h]<=qhead) h++;
                }
            }
            int now=0;
            if (h<=t) now=max(now,q[h]);
            if (top) now=max(now,st[top]);
            ans=(ans+(ll)now)%mod;
        }
    
        printf("%lld",ans);
    
        return 0;
    }
  • 相关阅读:
    【NOIP2013】花匠
    【DP合集】tree-knapsack
    【DP合集】m-knapsack
    【DP合集】背包 bound
    【DP合集】合并 union
    【DP合集】棋盘 chess
    BZOJ1026 [SCOI2009]windy数
    最长上升子序列 LIS nlogn
    再谈线性基
    数论问题算法模板
  • 原文地址:https://www.cnblogs.com/Maxwei-wzj/p/9793457.html
Copyright © 2011-2022 走看看