HDU 4699 - Editor - [对顶栈]

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4699

Problem Description

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

Sample Output
2
3

Hint

题意:

维护一个整数序列的编辑器,有以下五种操作,操作总数不超过 $10^6$。

$I \: x$:在当前光标位置之后插入一个整数 $x$,插入后光标移动到 $x$ 之后;

$D$:删除光标前的一个整数;

$L$:光标左移一格;

$R$:光标右移一格;

$Q \: k$:即 $S_i$ 为前 $i$ 个整数的和,查询 $S_1, S_2, \cdots, S_k$ 中的最大值。

题解:

已知 I,D,L,R 这四种操作都是在光标位置处发生,且操作完光标最多移动一个位置,因此可以用对顶栈的做法。

顾名思义,我们以光标为分界,分成左右两段序列分别由两个栈 $A,B$ 来维护,两个栈的栈顶相对。

同时我们可以开一个 $sum$ 数组来维护栈 $A$ 的前缀和,在开一个 $mx[i]$ 数组来保存 $sum[1], sum[2], \cdots, sum[i]$ 中的最大值。

AC代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
const int INF=0x3f3f3f3f;

stack<int> A,B;
int sum[maxn],mx[maxn];
void update()
{
    int p=A.size();
    sum[p]=sum[p-1]+A.top();
    mx[p]=max(mx[p-1],sum[p]);
}
int main()
{
    int q;
    while(cin>>q)
    {
        sum[0]=0;
        mx[0]=-INF;
        while(!A.empty()) A.pop();
        while(!B.empty()) B.pop();
        while(q--)
        {
            char op[3]; int k;
            scanf("%s",op);
            switch(op[0])
            {
            case ‘I‘:
                scanf("%d",&k);
                A.push(k);
                update();
                break;

            case ‘D‘:
                A.pop();
                break;

            case ‘L‘:
                if(A.empty()) break;
                B.push(A.top()); A.pop();
                break;

            case ‘R‘:
                if(B.empty()) break;
                A.push(B.top()); B.pop();
                update();
                break;

            case ‘Q‘:
                scanf("%d",&k);
                printf("%d\n",mx[k]);
                break;
            }
        }
    }
}

原文地址:https://www.cnblogs.com/dilthey/p/9896433.html

时间: 2024-10-05 23:25:24

HDU 4699 - Editor - [对顶栈]的相关文章

HDOJ 4699 Editor 对顶栈

编辑器 Editor Time Limit: 1Sec Memory Limit: 128 MB Sample Input 8I 2I -1I 1Q 3LDRQ 2 Sample Output 2 3 Hint The following diagram shows the status of sequence after each instruction: 分析: 最开始考虑到多次的插入.删除,我使用的链表. 但是由于涉及到求最大前缀和,每次都扫一遍会超时,于是学到了一种新方法:对顶栈,即指,

hdu 4699 Editor(双向链表+随便维护前缀和)

Editor Time Limit: 3000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 1532    Accepted Submission(s): 480 Problem Description Sample Input 8 I 2 I -1 I 1 Q 3 L D R Q 2 Sample Output 2 3 Hint The following d

Hdu 4699 Editor(Splay)

题目大意: 给出一个文本编辑器,按照图示的操作进行删减和添加. 思路分析: 对于如何维护左边最大,就要记录每个区间的左边最大,还有这个节点的值,还有子区间的和. 注意看题目,题目的要求输出左边最大是不能为空集的,意味着如果全部都是负数,那么就输出最左边的负数就好. 那么就要解决初始化的问题. 再有一点问题就是会有很多个连续的L ,R操作.所以要判断边界. #include <cstdio> #include <iostream> #include <vector> #i

hdu 4699

两个栈,光标前的元素一个栈,光标后的元素一个栈 sum[i]记录从1~i个元素之和,动态规划的状态方程是 dp[i] = max( dp[i-1], sum[i] ),dp[i]记录前i个元素的最大和值. #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<vector> #include

Hdu 4923(单调栈)

题目链接 Room and Moor Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 842    Accepted Submission(s): 250 Problem Description PM Room defines a sequence A = {A1, A2,..., AN}, each of which is eit

【HDU 4699】 Editor

[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=4699 [算法] 维护两个栈,一个栈放光标之前的数,另外一个放光标之后的数 在维护栈的同时求最大前缀和,即可 [代码] #include<bits/stdc++.h> using namespace std; const int MAXN = 1e6 + 5; const int INF = 2e9; class mstack { private : int tot; int s[MAXN];

HDOJ 4699 Editor 栈 模拟

用两个栈模拟: Editor Time Limit: 3000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 1913    Accepted Submission(s): 591 Problem Description Sample Input 8 I 2 I -1 I 1 Q 3 L D R Q 2 Sample Output 2 3 Hint The fol

HDU 4041 Eliminate Witches! (栈的模拟)

Eliminate Witches! Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1234    Accepted Submission(s): 461 Problem Description Kaname Madoka is a Magical Girl(Mahou Shoujo/Puella Magi). The duty of

HDU 1237 简单计算器(栈)

题目链接 Problem Description 读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值. Input 测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔.没有非法表达式.当一行中只有0时输入结束,相应的结果不要输出. Output 对每个测试用例输出1行,即该表达式的值,精确到小数点后2位. Sample Input 1 + 2 4 + 2 * 5 - 7 / 11 0 Sample Output 3.00