L i n k Link Link
J Z O J JZOJ JZOJ 3922 3922 3922
D e s c r i p t i o n Description Description
I n p u t Input Input
第一行包含一个数字N,表示操作的个数。
接下来包含N 行,每行包含一条命令。
O u t p u t Output Output
对于每个Q k 命令,输出一个整数表示这个操作的答案。
S a m p l e Sample Sample I n p u t Input Input
8
I 2
I -1
I 1
Q 3
L
D
R
Q 2
S a m p l e Sample Sample O u t p u t Output Output
2
3
H i n t Hint Hint
• 对于50% 的数据,N <= 1000。
• 对于80% 的数据,N <= 100000。
• 对于100% 的数据,N <= 1000000,插入的数字绝对值大小不会超过1000。
T r a i n Train Train o f of of T h o u g h t Thought Thought
对顶栈,前一个栈记录数列光标前的数, 后一个栈记录数列光标后的数,栈顶都是光标方向,这样一来,操作就很容易了:
f
[
i
]
表
示
前
i
个
最
大
前
缀
和
,
a
t
o
p
表
示
栈
a
的
栈
顶
,
b
t
o
p
表
示
栈
b
的
栈
顶
f[i]表示前i个最大前缀和, atop表示栈a的栈顶, btop表示栈b的栈顶
f[i]表示前i个最大前缀和,atop表示栈a的栈顶,btop表示栈b的栈顶
C o d e Code Code
#include<algorithm>
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
char c;
int atop, btop;
int n, a[1000005], b[1000005];
int f[1000005], sum[1000005];
int read()
{
int x = 0, flag = 1; char ch = getchar();
while (ch < '0' || ch > '9') { if (ch == '-') flag = -1;ch = getchar();}
while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
return x * flag;
}//快读
char readx()
{
char ch = getchar();
while (ch != 'I' && ch != 'D' && ch != 'L' && ch != 'R' && ch != 'Q') ch = getchar();
return ch;
}
int main()
{
f[0] = -1e9;
n = read();
for (int i = 1; i <= n; ++i)
{
int x;
c = readx();
if (c == 'I')
{
x = read();
a[++atop] = x;
sum[atop] =sum[atop - 1] + x;
f[atop] = max(f[atop - 1], sum[atop]);
}
if (c == 'D') atop--;
if (c == 'L') {
b[++btop] = a[atop];
atop--;
}
if (c == 'R') {
a[++atop] = b[btop];
btop--;
sum[atop] = sum[atop - 1] + a[atop];
f[atop] = max(f[atop - 1], sum[atop]);
}
if (c == 'Q') {
int k;
k = read();
printf("%d\n", f[k]);
}
}
}