你将要实现一个功能强大的整数序列编辑器。
在开始时,序列是空的。
编辑器共有五种指令,如下:
1、I x
,在光标处插入数值 xx。
2、D
,将光标前面的第一个元素删除,如果前面没有元素,则忽略此操作。
3、L
,将光标向左移动,跳过一个元素,如果左边没有元素,则忽略此操作。
4、R
,将光标向右移动,跳过一个元素,如果右边没有元素,则忽略次操作。
5、Q k
,假设此刻光标之前的序列为 a1,a2,…,an,输出 max1≤i≤kSi,其中 Si=a1+a2+…+ai。
输入格式
第一行包含一个整数 Q,表示指令的总数。
接下来 Q行,每行一个指令,具体指令格式如题目描述。
输出格式
每一个 Q k
指令,输出一个整数作为结果,每个结果占一行。
数据范围
1≤Q≤1e6
|x|≤1e3
1≤k≤n
输入样例:
8
I 2
I -1
I 1
Q 3
L
D
R
Q 2
输出样例:
2
3
样例解释
下图包含了对样例的过程描述:
思路:因为是在序列中进行操作,所以开一个对顶栈,栈A储存从序列开头到光标位置这一段序列;栈B储存当前光标位置到结尾这段序列。用sum数组记录A的前缀和,f数组维护最大前缀和 。
代码如下:
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
const int maxn = 1e6+10;
stack<int> a,b;
int sum[maxn],f[maxn];
int main(){
int q,x;
cin>>q;
f[0]=-0x3f3f3f3f;//细节:因为序列数字可能为负数,所以f[0]赋值为负无穷
sum[0]=0;
while(q--){
getchar();//吸收换行符
char ch=getchar();
if(ch=='I'){
cin>>x;
a.push(x);
//记录前缀和
sum[a.size()]=sum[a.size()-1]+a.top();
//维护最大前缀和
f[a.size()]=max(f[a.size()-1],sum[a.size()]);
}
if(ch=='D'){
if(!a.empty())//a要非空
a.pop();
}
if(ch=='L'){
if(!a.empty()){
b.push(a.top());
a.pop();
}
}
if(ch=='R'){
if(!b.empty()){
a.push(b.top());
b.pop();
//维护sum和f
sum[a.size()]=sum[a.size()-1]+a.top();
f[a.size()]=max(f[a.size()-1],sum[a.size()]);
}
}
if(ch=='Q') {
cin>>x;
cout<<f[x]<<endl;
}
}
return 0;
}