《算法竞赛进阶指南》0x11 栈 HDOJ4699 对顶栈

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4699

由于当前的操作只和序列中的某一个指定的位置有关,可以从光标处将序列划分两段,分别维护两个栈,再维护左栈的前缀和以及前缀和最大值。

代码如下:

#include<iostream>
using namespace std;
const int maxn = 1000010;
int n;
int  st1[maxn],st2[maxn],s[maxn],f[maxn];//双栈存储 
int N1,N2;
void Editer(){
    N1=0,N2=0;
    f[0]=-0x3f3f3f3f;
    while(n--){
        char c[10];
        scanf("%s",c);
        switch(c[0]){
            case 'I':
                scanf("%d",&st1[++N1]);
                s[N1]=s[N1-1]+st1[N1];//维护前缀和以及前缀和最大值
                f[N1]=max(f[N1-1],s[N1]);
                continue; 
            case 'D':
                if(!N1)continue;//光标在最前端
                N1--;
                continue; 
            case 'L':
                if(!N1)continue;
                st2[++N2]=st1[N1--];//将左栈中的栈顶放入右栈中
                continue;
            case 'R':
                if(!N2)continue;
                st1[++N1]=st2[N2--];
                s[N1]=s[N1-1]+st1[N1];//只维护左栈中的前缀和
                f[N1]=max(f[N1-1],s[N1]);
                continue;
            case 'Q':
                int k;
                scanf("%d",&k);
                printf("%d
",f[k]);//k不超过当前光标的位置 
        }
    }
}
int main(){
    while(scanf("%d",&n)!=EOF){
        Editer();
    }
    return 0;
}
原文地址:https://www.cnblogs.com/randy-lo/p/13150380.html