【题解】Editor [HDU4699]


传送: \(Editor\) \([HDU4699]\)

【题目描述】

有一个维护整数序列的强大编辑器,初始状态为空,下面提供五种不同的操作,给出的总操作次数 \(m \leqslant 1e6\) 。

\(“I,x”:\) 在光标后面添加一个整数 \(x\);

\(“D”:\) 删除光标前面的整数; \([Backspace]\)

\(“L”:\) 光标向左移动一个单位,除非它已在第一个位置; \([←]\)

\(“R”:\) 光标向右移动一个单位,除非它已在最后一个位置; \([→]\)

\(“Q,k”:\) 输出位置在k之前的最大前缀和。

【样例】

输入:
8
I 2
I -1
I 1
Q 3
L
D
R
Q 2
输出:
2
3

【数据范围】

\(1 \leqslant Q \leqslant 1e6\) \(,\) \(\left| x \right| \leqslant 1000\)


【分析】

对顶栈的炒鸡大水题

但毕竟当初花了那么对时间去搞栈,所以还是水写几篇题解吧...

仔细观察一下题目,问题的关键就在于\(“I”\),\(“D”\),即添加删除,这里我们先换个词,插入(~~啊~)和弹出。如果暂时不考虑光标左右移动的情况,那么每次删除的一定是最后一次插入的整数。后进先出一进一出的动作都在序列尾进行,这不就是个栈么?

那么如何解决光标左右移动的情况呢?

我们可以设置两个栈 \(L\) 和 \(R\),分别表示光标左右两边的所有数字,靠近光标左右两边的数为栈顶,序列首和序列尾为栈底。

对于每一次的操作:

插入\((“I,x”):\)把 \(x\) 丢进 \(L\)。

删除\((“D”):\)弹出 \(L\) 栈顶元素。

左移\((“L”):\)弹出 \(L\) 栈顶元素,并丢进 \(R\)。

右移\((“R”):\)弹出 \(R\) 栈顶元素,并丢进 \(L\)。

模拟一下。。。

当前的状态:

删除操作后的状态:

右移操作后的状态:

左移操作后的状态:

\((“Q,k”)\) 如何查询最大前缀和?

其实很简单,用一个变量 \(sum\) 表示当前位置的前缀和,再开一个数组 \(f[\) \(]\) 保存每个位置前面的最大前缀和。

当 \(L\) 中有元素 \(x\) 插入时,更新 \(sum\) 和 \(f[\) \(]\),当有元素弹出时,只更新 \(sum\) 。

这道题有两种实现方法:\(STL\) 和手写栈。

不过呢,用 \(STL\) 速度慢,代码长......懂我什么意思了吧....

【Code】

【STL】

#include<iostream>
#include<cstdio>
#include<stack>
using namespace std;
const int N=1e6+5;
stack<int> L,R;
int m,x,t,f[N],sum;char a;
inline int Max(int x,int y){return x>y?x:y;}
int main(){
while(scanf("%d",&m)>0){
t=sum=0;//用t表示当前L中的元素个数,同时也是光标左边的位置
while(!L.empty())L.pop();//清空两个栈
while(!R.empty())R.pop();//QAQ,QWQ,QAQ
f[0]=-0x7fffffff;//这个很重要,否则会WA一片
while(m--){
cin>>a;
if(a=='I'){//添加
scanf("%d",&x);
L.push(x);++t;//左边新增一个数x
f[t]=Max(f[t-1],sum+=x);//更新sum,f[tL]
}
else if(a=='D'&&!L.empty())sum-=L.top(),L.pop(),t--;//删除,sum也实时更新
else if(a=='L'&&!L.empty()){//左移
R.push(L.top());//左边减少一个数,放入右边
sum-=L.top();//更新sum
L.pop();t--;
}
else if(a=='R'&&!R.empty()){//右移
L.push(R.top());t++;//右边减少一个数,放入左边
f[t]=Max(f[t-1],sum+=R.top());//更新sum,f[tL]
R.pop();
}
else if(a=='Q')scanf("%d",&x),printf("%d\n",f[x]);//查询
}
}
}

【手写栈】

#include<iostream>
#include<cstdio>
using namespace std;
const int N=1e6+5;
int m,x,tL,tR,L[N],R[N],f[N],sum;char a;
inline int Max(int x,int y){return x>y?x:y;}
int main(){
while(scanf("%d",&m)>0){
tL=tR=sum=0;f[0]=-0x7fffffff;
while(m--){
cin>>a;
if(a=='I'){
scanf("%d",&x);
L[++tL]=x;
f[tL]=Max(f[tL-1],sum+=x);
}
if(a=='R'&&tR){
x=L[++tL]=R[tR--];
f[tL]=Max(f[tL-1],sum+=x);
}
if(a=='Q')scanf("%d",&x),printf("%d\n",f[x]);
if(a=='L'&&tL){sum-=L[tL],R[++tR]=L[tL--];}
if(a=='D'&&tL)sum-=L[tL--];
}
}
}

【题解】Editor [HDU4699]的更多相关文章

  1. hdu4699 Editor 2013 多校训练第十场 D题 数列维护 splay | 线段树 | 栈!!!!!

    题意:维护一个文本编辑,并且查询最大前缀和. 写了splay,wa了13次 过了之后觉着特傻逼.发现题解两个栈就可以了,光标前后维护两个栈,维护前面的栈的前缀和 和 最大前缀和. 哎,傻逼,太弱了,还 ...

  2. PC/UVa 题号: 110105/10267 Graphical Editor (图形化编辑器)题解

    #include<cstdio> #include<iostream> #include<string> #include<algorithm> #in ...

  3. HDU-4699 Editor 数据结构维护

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4699 题意:开始有一个光标,每次有5中操作:1,光标当前位置插入一个数,2,光标当前位置删除一个,3, ...

  4. hdu4699 Editor(双向链表或双栈对弹)

    本题就是两个要点: 1.数据结构的设计.显然可以使用双向链表来做,但是写双向链表的代码复杂度高.其实更好的方法是使用两个对弹的栈来做,而且没必要用STL的栈,就自己开两个数组简单搞一下就好了. 2.最 ...

  5. HDU4699:Editor

    浅谈栈:https://www.cnblogs.com/AKMer/p/10278222.html 题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=46 ...

  6. AHOI2006文本编辑器editor

    1269: [AHOI2006]文本编辑器editor Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1885  Solved: 683[Submit ...

  7. NOI2003 文本编辑器editor

    1507: [NOI2003]Editor Time Limit: 5 Sec  Memory Limit: 162 MBSubmit: 1908  Solved: 738[Submit][Statu ...

  8. Codeforces Round #350 (Div. 2) E. Correct Bracket Sequence Editor 栈 链表

    E. Correct Bracket Sequence Editor 题目连接: http://www.codeforces.com/contest/670/problem/E Description ...

  9. 【BZOJ1269/1507】[AHOI2006]文本编辑器editor Splay

    [BZOJ1269][AHOI2006]文本编辑器editor Description 这些日子,可可不和卡卡一起玩了,原来可可正废寝忘食的想做一个简单而高效的文本编辑器.你能帮助他吗?为了明确任务目 ...

随机推荐

  1. 精益车间管理如何实现?让APS排程系统来帮忙

    精益制造是企业全面的文化改变,它的主要目标是消灭任何形式的浪费.最明显的例子是在生产区域堆积的物料.在制品.等待客户来买的成品.它还可能包括员工不必的移动和不增值的许多流程,目标是在最小的库存,最短的 ...

  2. error LNK2019: 无法解析的外部符号 _main,该符号在函数 ___tmainCRTStartup 中被引用

    出现如下错误: error LNK2019: 无法解析的外部符号 _main,该符号在函数 ___tmainCRTStartup 中被引用 解决办法:

  3. Spark MLlib基本算法【相关性分析、卡方检验、总结器】

    一.相关性分析 1.简介 计算两个系列数据之间的相关性是统计中的常见操作.在spark.ml中提供了很多算法用来计算两两的相关性.目前支持的相关性算法是Pearson和Spearman.Correla ...

  4. windows10 docker安装使用

    一.安装部署 1.下载安装 https://hub.docker.com/editions/community/docker-ce-desktop-windows 需要注册完后,才可以下载.点击安装 ...

  5. 半小时上手laya

    laya的性能挺高,跟顶级的pixi.js差一些.比egret的性能强一些 laya的代码是偏功能性的, 观赏性,可读性比很差. 第一步,github上看了下,layaair二百星不到? 想不到堂堂的 ...

  6. python测试开发django-73.django视图 CBV 和 FBV

    前言 FBV(function base views) 就是在视图里使用函数处理请求,这一般是学django入门的时候开始使用的方式. CBV(class base views) 就是在视图里使用类处 ...

  7. JavaScript 实用工具库 : lodashjs

    首页地址:https://www.lodashjs.com/

  8. JDOJ 1606 数字三角形

    JDOJ 1606: 数字三角形 JDOJ传送门 Description 输入n,输出n的数字三角形 见样例 Input n Output n的数字三角形 Sample Input 4 Sample ...

  9. 前端/H5/JS:通过URL下载文件并转存到其他服务器(微信),Blob文件转File文件

    现在有一个图片URL,在自己服务器上,一个微信提供的媒体文件上传URL,我在前端通过JS实现转存微信服务器 1. http://file.xxx.com/asd.jpg 自己的 2.https://a ...

  10. BZOJ 3132: 上帝造题的七分钟 树状数组+差分

    这个思路很巧妙啊 ~ code: #include <cstdio> #include <algorithm> #define N 2050 #define ll int #d ...