Description
你正在设计一种新型的编辑器,这种编辑器可以高效地处理整数序列。
编辑器启动时,序列为空,光标指向序列的头部。编辑器支持下列 5 种操作:
1. I x 把整数 x 插入到光标位置;
2. D 删除光标之前的整数(保证光标不在序列的头部);
3. L 如果光标不在序列的头部,向左移动一个位置,否则不移动;
4. R 如果光标不在序列的尾部,向右移动一个位置,否则不移动;
5. Q k 假设光标之前的序列是 {a1, a2, … , an},求 S1, S2, … , Sk 的最大值(其中 Si = a1 +a2 +· · ·+ai )。保证 k ≤ n。
Input
第 1 行,1 个整数 Q,表示操作的数量。
接下来 Q 行,每行描述一个操作。
Output
对于每个操作 Q,输出对应的最大值。
Sample Input
8
I 2
I -1
I 1
Q 3
L
D
R
Q 2
Sample Output
2
3
Data Constraint
• 对于 30% 的数据,Q ≤ 1000;
• 对于 60% 的数据,Q ≤ 10^5;
• 对于 100% 的数据,1 ≤ Q ≤ 10^6, |x| ≤ 1000。
题解
询问只会光标之前的,修改位置也是光标处。
也就是说只需要动态维护光标之前的信息即可。
维护两个栈,一个记录光标前的信息,一个记录光标后的信息。
栈顶都是光标处。
移动光标就是一个出栈,一个进栈,
加入就是进栈,删除就是出栈。
每次向前面的那个栈加入元素的时候就维护一下需要查询的信息。
code
#include<queue>
#include<cstdio>
#include<iostream>
#include<algorithm>
#include <cstring>
#include <string.h>
#include <cmath>
#include <math.h>
#include <time.h>
#define ll long long
#define N 1000003
#define M 103
#define db double
#define P putchar
#define G getchar
#define inf 998244353
using namespace std;
char ch;
void read(int &n)
{
n=0;
ch=G();
while((ch<'0' || ch>'9') && ch!='-')ch=G();
ll w=1;
if(ch=='-')w=-1,ch=G();
while('0'<=ch && ch<='9')n=(n<<3)+(n<<1)+ch-'0',ch=G();
n*=w;
}
int max(int a,int b){return a>b?a:b;}
int min(int a,int b){return a<b?a:b;}
ll abs(ll x){return x<0?-x:x;}
ll sqr(ll x){return x*x;}
void write(ll x){if(x>9) write(x/10);P(x%10+'0');}
int z1[N],z2[N],s[N],mx[N];
int Q,t,top1,top2;
void ins1(int x)
{
top1++;
z1[top1]=x;
s[top1]=s[top1-1]+x;
mx[top1]=max(mx[top1-1],s[top1]);
}
void ins2(int x)
{
top2++;
z2[top2]=x;
}
int main()
{
memset(mx,128,sizeof(mx));
read(Q);
while(Q--)
{
for(ch=G();ch!='I' && ch!='D' && ch!='L' && ch!='R' && ch!='Q';ch=G());
if(ch=='I')read(t),ins1(t);else
if(ch=='D')top1--;else
if(ch=='L')
{
if(top1)ins2(z1[top1--]);
}else
if(ch=='R')
{
if(top2)ins1(z2[top2--]);
}else
{
read(t);
if(mx[t]<0)P('-');
write(abs(mx[t]));
P('\n');
}
}
return 0;
}