zoukankan      html  css  js  c++  java
  • 51Nod 算法马拉松28 C题 栈 单调队列

    欢迎访问~原文出处——博客园-zhouzhendong

    去博客园看该题解


    题目传送门 - 51Nod1952


    题意概括

      有一个栈,有3种操作:

      Ο 从栈顶加入一个元素

      Ο 从栈底加入一个元素

      Ο 从栈顶弹出一个元素

      现在,求每次操作后栈内元素的最大值和mod (1e9+7)

      n次操作,n<=1e7


    题解

      这题对于博主这样的蒟蒻,做出来了,万分欣喜。

      我们在搞一个栈的同时,维护一个单调不降的队列。

      然后在弹出栈的时候,如果队尾元素等于当前弹出的元素,那么队尾出队。

      至于两种进队,都是最基础的维护队列的方法。

      每次,最大值就是队尾元素值。


    代码

    #include <cstring>
    #include <cstdio>
    #include <cstdlib>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    typedef long long LL;
    const int N=1e7+5;
    const int mod=1e9+7;
    int n,a[N],b[N];
    int q[N*2],head,tail,st[N*2],first,last;
    LL A,B,C,x,aa,bb,MOD;
    int main(){
    	scanf("%d%lld%lld%lld%lld%lld%lld%lld",&n,&A,&B,&C,&x,&aa,&bb,&MOD);
    	for (int i=1,tot=0;i<=n;i++){
    		x=(x*aa+bb)%MOD;
    		LL xx=x%(A+B+C);
    		if (tot<=1||xx<A)
    			a[i]=0,b[i]=x,tot++;
    		else if (A<=xx&&xx<A+B)
    			a[i]=1,b[i]=x,tot++;
    		else
    			a[i]=2,tot--;
    	}
    	head=1e7+2,tail=head;
    	first=head,last=tail;
    	int ans=0;
    	for (int i=1;i<=n;i++){
    		if (a[i]==0){
    			st[++last]=b[i];
    			if (q[tail]<=b[i])
    				q[++tail]=b[i];
    		}
    		else if (a[i]==1){
    			st[first--]=b[i];
    			while (head<tail&&q[head+1]<b[i])
    				head++;
    			q[head--]=b[i];
    		}
    		else {
    			if (q[tail]==st[last])
    				tail--;
    			last--;
    		}
    		ans=(ans+q[tail])%mod;
    	}
    	printf("%d",ans);
    	return 0;
    }
    

      

  • 相关阅读:
    设计模式:访问者模式
    设计模式:模板模式
    三分法——求解凸性函数的极值问题——czyuan原创
    素数&&Miller_Rabbin
    【算法入门】深度优先搜索(DFS)
    快速幂取模
    hrbeu1280Turn the corner
    hdoj_3400Line belt
    【专题】三分法和牛顿迭代法总结
    zoj_3203Light Bulb
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/51Nod1952.html
Copyright © 2011-2022 走看看