HDU P4699 Editor___对顶栈

题目大意:

维护一个光标,支持多个操作:
I I x,在光标位置前插入一个数x
D D ,删除当前光标位置前一个数。
L,光标左移直至不能移动为止。
R R ,光标右移直至不能移动为止。
Q x x ,查询前x个数的前缀和的最大值。
操作数有Q个。

1|x|103 1 ≤ | x | ≤ 10 3
1Q106 1 ≤ Q ≤ 10 6

分析:

维护 2 2 个栈A,B 1Sum[]A 1 个 S u m [ ] 维 护 栈 A 的 前 缀 和
1f[]A 1 个 f [ ] 维 护 栈 A 的 前 缀 和 的 最 大 值
A A 存储[序列开头,当前光标位置]的一段子序列。
B倒着存储序列[当前光标位置+1,序列结尾]的一段子序列。
对于操作 I I x
我 们 将 x AAy 插 入 栈 A 中 , 在 栈 A 中 位 置 为 y ,此时 y y 为栈顶位置
Sum[y]=Sum[y1]+x
f[y]=max(f[y1],Sum[y]) f [ y ] = m a x ( f [ y − 1 ] , S u m [ y ] )
对于操作 D D
弹出A的栈顶即可
对于操作L
弹出A的栈顶然后插入到B中即可。
对于操作 R R
弹出B的栈顶,插入到 A A 中,
然后类似于I x x 的操作,维护Sum[],f[]
对于操作 Q Q x
回答 f[x] f [ x ] O(1) O ( 1 ) 得到。

代码:

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#define N 1000005

using namespace std;

int Sum[N], A[N], B[N], f[N];
int Q, x, l, r;
char c[2];

int main() {
    while (~scanf("%d", &Q)) {
           l = r = 1;
           while (Q--) {
              scanf("%s", c);
              switch (c[0]) {
                    case 'D':
                           if (l > 1) l--;
                           break;
                    case 'I':
                           scanf("%d", &x);
                           A[l++] = x;
                           if (l == 2) Sum[1] = f[1] = x;
                                  else {
                                     Sum[l - 1] = Sum[l - 2] + x;
                                       f[l - 1] = max(f[l - 2], Sum[l - 1]);
                             }
                      break;
                 case 'L':
                        if (l > 1) B[r++] = A[--l];
                        break;
                 case 'Q':
                        scanf("%d", &x);
                        printf("%d\n", f[x]);
                      break;
                 case 'R':
                        if (r > 1) {
                               x = B[--r];
                                 A[l++] = x;
                                 if (l == 2) Sum[1] = f[1] = x;
                                        else {
                                        Sum[l - 1] = Sum[l - 2] + x;
                                       f[l - 1] = max(f[l - 2], Sum[l - 1]);
                                   }
                      }
                      break;
           }
        }
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值