洛谷 P1383 高级打字机==codevs 3333 高级打字机
P1383 高级打字机
题目描述
早苗入手了最新的高级打字机。最新款自然有着与以往不同的功能,那就是它具备撤销功能,厉害吧。
请为这种高级打字机设计一个程序,支持如下3种操作:
1.T x:在文章末尾打下一个小写字母x。(type操作)
2.U x:撤销最后的x次修改操作。(Undo操作)
(注意Query操作并不算修改操作)
3.Q x:询问当前文章中第x个字母并输出。(Query操作)
文章一开始可以视为空串。
输入输出格式
输入格式:
第1行:一个整数n,表示操作数量。
以下n行,每行一个命令。保证输入的命令合法。
输出格式:
每行输出一个字母,表示Query操作的答案。
输入输出样例
7
T a
T b
T c
Q 2
U 2
T c
Q 2
b
c
说明
【数据范围】
对于40%的数据 n<=200;
对于100%的数据 n<=100000;保证Undo操作不会撤销Undo操作。
<高级挑战>
对于200%的数据 n<=100000;Undo操作可以撤销Undo操作。
<IOI挑战>
必须使用在线算法完成该题。
50分代码(栈模拟):
#include<cstdio>
using namespace std;
#define N 51000
int top,T;
char st[N];
int main(){
scanf("%d",&T);
while(T--){
char c1[],c2[];int x;
scanf("%s",c1);
if(c1[]=='T'){
scanf("%s",c2);
st[++top]=c2[];
}
if(c1[]=='U'){
scanf("%d",&x);
top-=x;
}
if(c1[]=='Q'){
scanf("%d",&x);
printf("%c\n",st[x]);
}
}
return ;
}
题解:
因为Undo操作只能撤销Type操作,所以Undo x 实际上就是删除文章末尾x个字母。用一个栈即可解决(每个字母最多进出一次)。
<高级挑战> (考虑到部分选手水平较高,故设此附加题)
本题虽为2012年IOI的题目,但只要使用离线算法,就成为只需noip级别编程水平的题目了。
以下声明一些定义:(对于此类题目以及各种可持久化数据结构的离线解法的思考很有帮助)
版本:接受第1--i个修改操作(包含Type和Undo)后的状态称为版本i。版本0为初始状态。
版本链:一般的数据结构题目只有各种修改命令(比如本题的Type操作),那么所有版本就会呈链状排列。

这种情况下只需要设计一个合理的数据结构依次执行操作即可。
版本树:Undo x撤销最近的x次修改操作,实际上就是当前版本还原为x次操作前的版本,换句话说,版本i = 版本i-x-1。

如图所示,所有版本呈树状排列,版本0为根。
读入所有操作并建树,对这颗版本树按欧拉序求出所有版本。上图中就是按0->1->4...4->1->0->2->3->2->0的顺序遍历,同样使用栈就能计算出所有的版本,然后在对应的版本上解决询问即可。
到此,就得到了时空复杂度均为O(n)的离线算法。
能解决这类题目的条件是:
1.允许使用离线算法,进而求出版本树,并允许把询问挂到树的节点上。
2.所有操作都是可逆的。只有所有操作都是可逆的,才能按欧拉序依次求出各版本。如本题的Type操作的逆操作就是弹出栈顶,Undo操作则根本不需要修改(Undo前后2个版本相同)。
相关题目:crisis 60% (2012 国家集训队hw2出题互测\卓亮)
<IOI挑战>
Trie+倍增法寻祖 O(nlogn)
各种可持久化数据结构:可持久化块状数组 O(nsqrtn)
可持久化跳表(与Trie解法相近) O(nlogn)
......
因超出noip范围不做更多展开。
AC代码(手写主席树):
#include<cstdio>
using namespace std;
const int R=1e5,N=(R+)*;
int n,m,now,sz,root[R+],ls[N],rs[N],len[N];
char s[N];
inline int read(){
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
void insert(int &k,int last,int l,int r,int pos,int c){
k=++sz;
if(l==r){s[k]=c;return ;}
ls[k]=ls[last];
rs[k]=rs[last];
int mid=l+r>>;
if(pos<=mid) insert(ls[k],ls[last],l,mid,pos,c);
else insert(rs[k],rs[last],mid+,r,pos,c);
}
void query(int &k,int last,int l,int r,int pos){
if(l==r){putchar(s[k]);putchar('\n');return ;}
int mid=l+r>>;
if(pos<=mid) query(ls[k],ls[last],l,mid,pos);
else query(rs[k],rs[last],mid+,r,pos);
}
int main(){
n=read();
for(int i=,x;i<=n;i++){
char op=,ch=;
for(;op<'A'||op>'Z';op=getchar());
if(op=='T'){
for(;ch<'a'||ch>'z';ch=getchar());
now++;
len[now]=len[now-]+;
insert(root[now],root[now-],,R,len[now],ch);
}
else if(op=='U'){
x=read();
now++;
root[now]=root[now-x-];
len[now]=len[now-x-];
}
else x=read(),query(root[now],root[now-],,R,x);
}
return ;
}
AC代码(rope标程):
#include<cstdio>
#include<iostream>
#include<ext/rope>
using namespace std;
using namespace __gnu_cxx;
const int maxn=1e5+;
rope<char> *his[maxn];
int n,m;
inline char getC(){
for(register char ch=getchar();;ch=getchar()) if((ch>='A'&&ch<='Z')||(ch>='a'&&ch<='z')) return ch;
}
inline int getint(){
register int x=,f=;
register char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
int main(){
n=getint();
his[]=new rope<char>();
for(int i=;i<=n;i++){
char opt=getC();
if(opt=='T'){
m++;
his[m]=new rope<char>(*his[m-]);//就是这一句!它可以实现O(1)的拷贝历史版本,由于rope的底层是平衡树,copy时copy根节点就行了;用它就可以轻松实现可持久化数组
char x=getC();
his[m]->push_back(x);
}else if(opt=='U'){
int x=getint();
m++;
his[m]=new rope<char>(*his[m-x-]); }else if(opt=='Q'){
int x=getint()-;
putchar(his[m]->at(x));
putchar('\n');
}
}
return ;
}
洛谷 P1383 高级打字机==codevs 3333 高级打字机的更多相关文章
- 洛谷P1395 会议(CODEVS.3029.设置位置)(求树的重心)
To 洛谷.1395 会议 To CODEVS.3029 设置位置 题目描述 有一个村庄居住着n个村民,有n-1条路径使得这n个村民的家联通,每条路径的长度都为1.现在村长希望在某个村民家中召开一场会 ...
- codevs 3333 高级打字机
3333 高级打字机 题目描述 Description 早苗入手了最新的高级打字机.最新款自然有着与以往不同的功能,那就是它具备撤销功能,厉害吧. 请为这种高级打字机设计一个程序,支持如下3种操作 ...
- 洛谷P1432 倒水问题(CODEVS.1226)
To 洛谷.1432 倒水问题 题目背景 In the movie "Die Hard 3", Bruce Willis and Samuel L. Jackson were co ...
- 洛谷 P2155 BZOJ 2186 codevs 2301 [SDOI2008]沙拉公主的困惑
题目描述 大富翁国因为通货膨胀,以及假钞泛滥,政府决定推出一项新的政策:现有钞票编号范围为1到N的阶乘,但是,政府只发行编号与M!互质的钞票.房地产第一大户沙拉公主决定预测一下大富翁国现在所有真钞票的 ...
- 洛谷P1650赛马与codevs 2181 田忌赛马
洛谷P1650 赛马 题目描述 我国历史上有个著名的故事: 那是在2300年以前.齐国的大将军田忌喜欢赛马.他经常和齐王赛马.他和齐王都有三匹马:常规马,上级马,超级马.一共赛三局,每局的胜者可以从负 ...
- 洛谷 P1383 codevs 3333 高级打字机
题目描述 早苗入手了最新的高级打字机.最新款自然有着与以往不同的功能,那就是它具备撤销功能,厉害吧. 请为这种高级打字机设计一个程序,支持如下3种操作: 1.T x:在文章末尾打下一个小写字母x.(t ...
- 【洛谷P1383 高级打字机】
题目描述 早苗入手了最新的高级打字机.最新款自然有着与以往不同的功能,那就是它具备撤销功能,厉害吧. 请为这种高级打字机设计一个程序,支持如下3种操作: 1.T x:在文章末尾打下一个小写字母x.(t ...
- 洛谷 P1262 间谍网络==Codevs 4093 EZ的间谍网络
4093 EZ的间谍网络 时间限制: 10 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 由于外国间谍的大量渗入,国家安全正处于高度的危机之中.如果A间谍手中掌握着关于B ...
- 洛谷——P1002 过河卒||codevs——T1010 过河卒
https://www.luogu.org/problem/show?pid=1002#sub||http://codevs.cn/problem/1010/ 题目描述 棋盘上A点有一个过河卒,需要走 ...
随机推荐
- 使用HTML5+调用手机摄像头和相册
前言:前端时间使用HTML5做了一个WEB端APP,其中用到了H5页面调用手机摄像头的功能,当时也是花了不少时间去研究.最终是采用了HTML5plus(HTML5+)的方式完成了该功能,现将具体方法简 ...
- CSS工具、CSS重置(CSS Reset)
样式重置的目的是减少浏览器的不一致性,例如line-height,margin,标题的font-size大小等等.样式重置经常在CSS框架中出现. 这里的重置样式故意写的很一般,例如没有为body元素 ...
- 服务器端编程心得(二)—— Reactor模式
最近一直在看游双的<高性能linux服务器编程>一书,下载链接: http://download.csdn.net/detail/analogous_love/9673008 书上是这么介 ...
- copy on write
yl::string CBaseAutopProcessor::AddAuthorizedInfo(const yl::string & strOriginalUrl, const yl::s ...
- 零基础入门学习Python(24)--递归:汉诺塔
知识点 这节课主要讲解用递归的方法,实现汉诺塔的解答 对于游戏的玩法,我们可以简单分解为三个步骤: 1) 将前63个盘子从X移动到Y上. 2) 将最底下的第64个盘子从X移动到Z上. 3) 将Y上的6 ...
- js 技巧 (十)广告JS代码效果大全 【1】
广告JS代码效果大全 1.[普通效果] 现在很多网站广告做的如火如荼,现在我就来介绍一下常见的对联浮动广告效果的代码使用方法,介绍的这种效果,在1024*768分辨率下正常显示,在800*60 ...
- 简述FTP主动模式与被动模式
1 FTP工作模式 2 不同模式FTP面临的问题 3 主动模式的FTP连接建立连接主要步骤 客户端打开一个随机的端口(端口号大于1024,在这里,我们称它为x),同时一个FTP进程连接至服务器的21号 ...
- Matlab学习笔记(一)
一.MATLAB概述 (一)运行环境 命令行窗口(Command Window) 表 1-1 数据显示格式设置(e_one_1.m) 格式 实例 说明 format short 3.1416 小数点后 ...
- 笔记——collections模块
collections模块 collections模块在内置数据类型(dict.list.set.tuple)的基础上,还提供了几个额外的数据类型:ChainMap.Counter.deque.def ...
- node学习的一些网站
Node.js 包教不包会 篇幅比较少 node express 入门教程 nodejs定时任务 一个nodejs博客 [NodeJS 学习笔记04]新闻发布系统 过年7天乐,学nodejs 也快乐 ...