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

题目描述

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

请为这种高级打字机设计一个程序,支持如下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\n",a[now]);
        }
    }
    return 0;
}
posted @ 2020-07-05 20:37  牛大了的牛大  阅读(186)  评论(0编辑  收藏  举报