jzoj数列编辑器【栈】

>Description
在这里插入图片描述


>Input
第一行包含一个数字N,表示操作的个数。
接下来包含N 行,每行包含一条命令。

>Output
对于每个Q k 命令,输出一个整数表示这个操作的答案。


>Sample Input
8
I 2
I -1
I 1
Q 3
L
D
R
Q 2

>Sample Output
2
3

• 对于50% 的数据,N <= 1000。
• 对于80% 的数据,N <= 100000。
• 对于100% 的数据,N <= 1000000,插入的数字绝对值大小不会超过1000。


>解题思路

部分分做法:直接暴力。

正解:
O(n),可以用两个栈分别对当前光标前和光标后数字的进行维护,光标的移动只需要将一个栈顶元素移动到另一个栈就行了,并且题目说只会查询光标前的数据,所以答案也只需要在光标前的栈中维护。


>代码

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

int n, y, t, ans[1000005], s[1000005], a[1000005], b[1000005];
char x;

int read () //int类型快读
{
	int l = 0;
	char c = getchar(), cc;
	while (c > '9' || c < '0') cc = c, c = getchar();
	while (c <= '9' && c >= '0')
	{
		l = l * 10 + c - '0';
		c = getchar();
	}
	if (cc == '-') return -l; //记得判断正负!
	return l;
}

char rread() //字符快读
{
	char c = getchar ();
	while (c != 'I' && c != 'L' && c != 'R' && c != 'D' && c != 'Q') //如果不是题目描述的那几个字符就继续读入
	  c = getchar ();
	return c;
}

int main()
{
	ans[0] = -1e9; //由于读入的数可能是负数,所以初值要设成一个很小的数
	n = read();
	for (int i = 1; i <= n; i++)
	{
		x = rread();
		if (x == 'I')
		{
			y = read();
			a[++a[0]] = y; //把y放入光标前面的栈 (a[0]为栈的长度)
			s[a[0]] = s[a[0] - 1] + y; //前缀和
			ans[a[0]] = max (ans[a[0] - 1], s[a[0]]); //维护ans
		} 
		if (x == 'D')
		{
			a[0]--; //去除光标前面的数
		}
		if (x == 'L')
		{
			b[++b[0]] = a[a[0]];
			a[0]--; //把光标前面的数从a栈移到b栈
		}
		if (x == 'R')
		{
			a[++a[0]] = b[b[0]]; //把光标后面的数从b栈移到a栈
			s[a[0]] = s[a[0] - 1] + a[a[0]];
			ans[a[0]] = max (ans[a[0] - 1], s[a[0]]);
			b[0]--;
		}
		if (x == 'Q')
		{
			y = read();
			printf ("%d\n", ans[y]); //直接输出
		}
	}
	return 0;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值