你将要实现一个功能强大的整数序列编辑器。
在开始时,序列是空的。
编辑器共有五种指令,如下:
1、“I x”,在光标处插入数值x。
2、“D”,将光标前面的第一个元素删除,如果前面没有元素,则忽略此操作。
3、“L”,将光标向左移动,跳过一个元素,如果左边没有元素,则忽略此操作。
4、“R”,将光标向右移动,跳过一个元素,如果右边没有元素,则忽略次操作。
5、“Q k”,假设此刻光标之前的序列为a1,a2,…,an,输出,其中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
样例解释
下图包含了对样例的过程描述:
刚开始看的时候确实有点蒙。。。但仔细想想还是可以做的。我们可以先用一个栈来对I,D,和Q进行操作,即如果没有L和R的话这就是一个很简单的栈套一个前缀和维护。它的代码也不难写出:
void push(int x)
{
stkl[++tl]=x;
sum[tl]=sum[tl-1]+x;
ans[tl]=max(ans[tl-1],sum[tl]);
}
int main()
{
IOS;
int t,x,k;
cin>>t;
ans[0]=-inf;
while (t--){
char s[3];
cin>>s;
if (s[0]=='I'){
cin>>x;
push(x);
}
else if (s[0]=='D'){
if (tl>0) tl--;
}
else {
cin>>k;
cout<<ans[k]<<endl;
}
}
return 0;
}
那么当他加上了L和R的操作的时候回怎么样呢?对于L操作向左移,那么我们还是将stkl的栈顶pop掉,但由于之后的数列并没有消失,所以我们应该用一个东西保存它们。用什么呢?当然还是栈啦!它每向左移一位,我们的栈顶就往上加,当它向右移的时候我们只需要将这个栈顶pop掉同时将它的值赋给stkl[++tl]。如图所示:
于是这题就完美的结束啦!
以下是AC代码:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define IOS ios::sync_with_stdio(false)
const int mac=1e6+10;
const int inf=1e9+10;
int stkl[mac],sum[mac],stkr[mac],tl,tr,ans[mac];
void push(int x)
{
stkl[++tl]=x;
sum[tl]=sum[tl-1]+x;
ans[tl]=max(ans[tl-1],sum[tl]);
}
int main()
{
IOS;
int t,x,k;
cin>>t;
ans[0]=-inf;
while (t--){
char s[3];
cin>>s;
if (s[0]=='I'){
cin>>x;
push(x);
}
else if (s[0]=='D'){
if (tl>0) tl--;
}
else if (s[0]=='L'){
if (tl>0) stkr[++tr]=stkl[tl--];
}
else if (s[0]=='R'){
if (tr>0){
stkl[++tl]=stkr[tr--];
sum[tl]=sum[tl-1]+stkl[tl];
ans[tl]=max(ans[tl-1],sum[tl]);
}
}
else {
cin>>k;
cout<<ans[k]<<endl;
}
}
return 0;
}