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


    题目描述

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

    请为这种高级打字机设计一个程序,支持如下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;
    }
  • 相关阅读:
    模块jieba库的使用
    模块wordcloud库的使用
    爬取哔哩哔哩网站弹幕
    爬虫讲解
    基本统计值计算
    数据类型及元素元组
    pyinstall的安装及使用
    面向对象介绍
    re模块
    logging模块
  • 原文地址:https://www.cnblogs.com/LJA001162/p/13251595.html
Copyright © 2020-2023  润新知