题目地址:
https://www.acwing.com/problem/content/130/
你将要实现一个功能强大的整数序列编辑器。在开始时,序列是空的。编辑器共有五种指令,如下:
1、I x
,在光标处插入数值
x
x
x。
2、D
,将光标前面的第一个元素删除,如果前面没有元素,则忽略此操作。
3、L
,将光标向左移动,跳过一个元素,如果左边没有元素,则忽略此操作。
4、R
,将光标向右移动,跳过一个元素,如果右边没有元素,则忽略次操作。
5、Q k
,假设此刻光标之前的序列为
a
1
,
a
2
,
…
,
a
n
a_1,a_2,…,a_n
a1,a2,…,an,输出
max
1
≤
i
≤
k
S
i
\max_{1≤i≤k}S_i
max1≤i≤kSi,其中
S
i
=
a
1
+
a
2
+
…
+
a
i
S_i=a_1+a_2+…+a_i
Si=a1+a2+…+ai。
输入格式:
第一行包含一个整数
Q
Q
Q,表示指令的总数。接下来
Q
Q
Q行,每行一个指令,具体指令格式如题目描述。
输出格式:
每一个Q k
指令,输出一个整数作为结果,每个结果占一行。
数据范围:
1
≤
Q
≤
1
0
6
1≤Q≤10^6
1≤Q≤106
∣
x
∣
≤
1
0
3
|x|≤10^3
∣x∣≤103
1
≤
k
≤
n
1≤k≤n
1≤k≤n
可以用对顶栈。对于最后一个询问,只需要另外存两个数组,一个是 s s s,存前缀和,递推式 s [ i ] = s [ i − 1 ] + A [ i ] s[i]=s[i-1]+A[i] s[i]=s[i−1]+A[i],另一个是 f f f,存 A [ 1 : i ] A[1:i] A[1:i]的最大前缀和,递推式 f [ i ] = max { f [ i − 1 ] , s [ i ] } f[i]=\max\{f[i-1], s[i]\} f[i]=max{f[i−1],s[i]}。这样对于最后一个询问只需要按照 f f f的值应答即可。代码如下:
#include <iostream>
using namespace std;
const int N = 1e6 + 10;
int m;
int stk[N], top1 = 1, top2 = N - 1;
int sum[N], f[N];
int main() {
f[0] = -1e9;
scanf("%d", &m);
while (m--) {
char op[2];
int x;
scanf("%s", op);
if (*op == 'I' || *op == 'Q') scanf("%d", &x);
if (*op == 'I') {
sum[top1] = sum[top1 - 1] + x;
f[top1] = max(f[top1 - 1], sum[top1]);
stk[top1++] = x;
} else if (*op == 'D') {
if (top1 > 1) top1--;
} else if (*op == 'L') {
if (top1 > 1) stk[top2--] = stk[--top1];
} else if (*op == 'R') {
if (top2 < N - 1) {
stk[top1++] = stk[++top2];
int top = top1 - 1;
sum[top] = sum[top - 1] + stk[top];
f[top] = max(f[top - 1], sum[top]);
}
} else printf("%d\n", f[x]);
}
return 0;
}
每次操作时间复杂度 O ( 1 ) O(1) O(1),空间 O ( n ) O(n) O(n), n n n为被插入的字符总数。