【对顶栈】 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]);
}
}
}

浙公网安备 33010602011771号