高级打字机
2016-06-20 16:37
155 查看
【题目描述】
早苗入手了最新的高级打字机。最新款自然有着与以往不同的功能,那就是它具备撤销功能,厉害吧。
请为这种高级打字机设计一个程序,支持如下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挑战>
必须使用在线算法完成该题。
题解:
因为Undo操作只能撤销Type操作,所以Undo x 实际上就是删除文章末尾x个字母。用一个栈即可解决(每个字母最多进出一次)。
<高级挑战> (考虑到部分选手水平较高,故设此附加题)
本题虽为2012年IOI的题目,但只要使用离线算法,就成为只需noip级别编程水平的题目了。
以下声明一些定义:(对于此类题目以及各种可持久化数据结构的离线解法的思考很有帮助)
版本:接受第1--i个修改操作(包含Type和Undo)后的状态称为版本i。版本0为初始状态。
版本链:一般的数据结构题目只有各种修改命令(比如本题的Type操作),那么所有版本就会呈链状排列。
View Code
早苗入手了最新的高级打字机。最新款自然有着与以往不同的功能,那就是它具备撤销功能,厉害吧。
请为这种高级打字机设计一个程序,支持如下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挑战>
必须使用在线算法完成该题。
题解:
因为Undo操作只能撤销Type操作,所以Undo x 实际上就是删除文章末尾x个字母。用一个栈即可解决(每个字母最多进出一次)。
<高级挑战> (考虑到部分选手水平较高,故设此附加题)
本题虽为2012年IOI的题目,但只要使用离线算法,就成为只需noip级别编程水平的题目了。
以下声明一些定义:(对于此类题目以及各种可持久化数据结构的离线解法的思考很有帮助)
版本:接受第1--i个修改操作(包含Type和Undo)后的状态称为版本i。版本0为初始状态。
版本链:一般的数据结构题目只有各种修改命令(比如本题的Type操作),那么所有版本就会呈链状排列。
#include<cstdio> #include<iostream> using namespace std; #define N 10000100 int root ,len ,lc ,rc ,tot; char s[N*2]; inline void ins(int &y,int x,int l,int r,int pos,char c) { y=++tot; if(l==r) {s[y]=c;return ;} else { int mid=l+r>>1;lc[y]=lc[x];rc[y]=rc[x]; if(pos<=mid) ins(lc[y],lc[x],l,mid,pos,c); else ins(rc[y],rc[x],mid+1,r,pos,c); } } inline void query(int y,int l,int r,int pos) { if(l==r){printf("%c\n",s[y]);return ;} else { int mid=l+r>>1; if(pos<=mid) query(lc[y],l,mid,pos); else query(rc[y],mid+1,r,pos); } } int main() { int n,cnt=0,lm=1,rm=100000; scanf("%d",&n); for(int i=1,x;i<=n;i++) { char cmd[2],ch[2]; scanf("%s",cmd); if(cmd[0]=='T') { scanf("%s",ch);cnt++;len[cnt]=len[cnt-1]+1; ins(root[cnt],root[cnt-1],lm,rm,len[cnt],ch[0]); } else if(cmd[0]=='U') { scanf("%d",&x);cnt++; root[cnt]=root[cnt-x-1]; len[cnt]=len[cnt-x-1]; } else scanf("%d",&x),query(root[cnt],lm,rm,x); } return 0; }
View Code
相关文章推荐
- spring mvc 异常统一处理方式
- windbg符号
- debug(3) 死机原因及解决方法
- DBUnit使用案例
- 谥号与谥号制度
- 手机摄像头技术
- (赋值运算付)short s=1, s = s+1; short s=1, s+=1; 上面两个代码有没有问题,如果有,那里有问题?
- swiper的基础使用(九)
- 12以内阶乘、自然对数e及e的x次方的计算(Factorial)
- 给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。
- 可爱且功能增强版的银行储存系统
- 杂记,待丰富-2016.06.20
- 数据结构_P19
- java.lang.IllegalStateException: Cannot start this animator on a detached view!
- etcd安装测试
- DHTML:<select>
- swiper的基础使用(八)
- linux 开启 自动挂载U盘 权限的设置
- jQuery操作Form表单元素
- 12步入门Python中的decorator装饰器使用方法