[入门组模拟赛]高级打字机

Posted lja001162

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[入门组模拟赛]高级打字机相关的知识,希望对你有一定的参考价值。

题目描述

早苗入手了最新的高级打字机。最新款自然有着与以往不同的功能,那就是它具备撤销功能,厉害吧。

请为这种高级打字机设计一个程序,支持如下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

提示

    对于20%的数据 n<=200;

    对于50%的数据 n<=100000;保证Undo操作不会撤销Undo操作。

    对于100%的数据 n<=100000;Undo操作可以撤销Undo操作。

#include<bits/stdc++.h>
using namespace std;
const int N=100001;
int cnt,n,w,f[N][23],g[N][23],close[N],head[N],num[N]; 
char s[10],c[10],a[N];
void insert()
{
    num[cnt]=num[cnt-1]+1;
    if(a[cnt-1]==U) close[cnt]=close[cnt-1];
    else close[cnt]=cnt-1;
    if(a[cnt-1]==U) f[cnt][0]=close[cnt-1];
    else f[cnt][0]=cnt-1;
    head[cnt]=cnt-1;
    for(int i=1;i<=20;i++)
        f[cnt][i]=f[f[cnt][i-1]][i-1];    
    g[cnt][0]=cnt-1;
    for(int i=1;i<=20;i++)
        g[cnt][i]=g[g[cnt][i-1]][i-1];
}
void Undo(int x)
{
    x--;
    int now=cnt;
    a[++cnt]=U;
    for(int i=20;i>=0;i--)
        if((1<<i)<=x)
        {
            x-=(1<<i);
            now=g[now][i];
        }
    now--;
    head[cnt]=now;
    num[cnt]=num[now];
    if(a[now]==U) close[cnt]=close[now];
    else close[cnt]=now;
    if(a[now]==U) f[cnt][0]=close[now];
    else f[cnt][0]=now;
    for(int i=1;i<=20;i++)
        f[cnt][i]=f[f[cnt][i-1]][i-1];
    g[cnt][0]=cnt-1;
    for(int i=1;i<=20;i++)
        g[cnt][i]=g[g[cnt][i-1]][i-1];    
}
int main()
{
    scanf("%d",&n);
    a[0]=A;
    close[0]=0;
    for(int i=1;i<=n;i++)
    {
        scanf("%s",s);
        if(s[0]==T)
        {
            scanf("%s",c);
            a[++cnt]=c[0]; 
            insert();
            continue;
        } 
        if(s[0]==U)
        {
            scanf("%d",&w);
            Undo(w);
            continue;
        }
        if(s[0]==Q)
        {
            scanf("%d",&w);
            w=num[cnt]-w+1;
            if(w<=0)
                w=1;
            if(a[cnt]!=U)
                w--;
            int now=cnt;
            for(int i=20;i>=0;i--)
                if((1<<i)<=w)
                {
                    w-=(1<<i);
                    now=f[now][i];
                }
            printf("%c
",a[now]);
        }
    }
    return 0;
}

以上是关于[入门组模拟赛]高级打字机的主要内容,如果未能解决你的问题,请参考以下文章

NOIP模拟 6.28

6.19 noip模拟题(题目及解析转自 hzwer 2014-3-15 NOIP模拟赛)

markdown 打字稿...编码说明,提示,作弊,指南,代码片段和教程文章

[入门组模拟赛[难]]灯塔

2012-10-20 NOIP模拟赛

2016.6.19 模拟考试