【对顶栈】 Editor

传送门

题意

开始序列为空,一共有5个可能的操作

  • \((L, x)\) :在光标处插入\(x\)
  • \(D\):将光标前一个元素删除,如果没有忽略
  • \(L\):光标左移一个位置,左边无元素则忽略
  • \(R\):光标右移一个位置,右边无元素则忽略
  • \((Q, k)\):输出\(k\)之前的最大前缀和,\(k\)一定位于光标处或光标之前

数据范围

\(1\leq Q\leq 10^{6}\)
\(|x| \leq 10^{3}\)
\(1\leq k\leq n\)

题解

对顶栈,光标前的在\(A\),光标后的在\(B\)\(f[i]\)表示\(i\)之前的最大前缀和,
在插入右移操作的时候更新\(f\)\(sum\) 即可。

Code

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int sum[N],f[N],idx;
stack<int>stk1,stk2;
int main(){
    int Q; scanf("%d", &Q);
    f[0] = -0x3f3f3f3f;
    sum[0] = 0;
    char op[2];
    while(Q --){
        scanf("%s", op);

        if(*op == 'I'){
            int x; scanf(" %d", &x);
            idx++;
            stk1.push(x);
            sum[stk1.size()] = sum[stk1.size() - 1] + x;
            f[stk1.size()] = max(f[stk1.size() - 1], sum[stk1.size()]);
        }
        else if(*op == 'D'){
            if(stk1.size()) stk1.pop();
        }
        else if(*op == 'L'){
            if(stk1.size()){
                stk2.push(stk1.top());
                stk1.pop();
            }
        }
        else if(*op == 'R'){
            if(stk2.size()) {
                int x = stk2.top();
                stk1.push(x); stk2.pop();
                sum[stk1.size()] = sum[stk1.size() - 1] + x;
                f[stk1.size()] = max(f[stk1.size() - 1], sum[stk1.size()]);
            }
        }
        else{
            int k; scanf(" %d",&k);
            printf("%d\n", f[k]);
        }
    }
}
posted @ 2020-07-11 00:34  Hyx'  阅读(188)  评论(0)    收藏  举报