codevs 3333 高级打字机

时间限制: 1 s
 空间限制: 256000 KB
 题目等级 : 大师 Master
题目描述 Description

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

请为这种高级打字机设计一个程序,支持如下3种操作:

1.T x:在文章末尾打下一个小写字母x。(type操作)

2.U x:撤销最后的x次修改操作。(Undo操作)

(注意Query操作并不算修改操作)

3.Q x:询问当前文章中第x个字母并输出。(Query操作)

文章一开始可以视为空串。

输入描述 Input Description

第1行:一个整数n,表示操作数量。

以下n行,每行一个命令。保证输入的命令合法。

输出描述 Output Description

每行输出一个字母,表示Query操作的答案。

样例输入 Sample Input

7

T a

T b

T c

Q 2

U 2

T c

Q 2

样例输出 Sample Output

b

c

数据范围及提示 Data Size & Hint

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

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

<高级挑战>

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

 

裸主席树

屠龙宝刀点击就送

#include <cstdio>
#define N 2005000
char str[N];
int ls[N],rs[N],R=N/20,n,len[N],rt[N],now,tot;
void update(int l,int r,int x,int &y,int t,char v)
{
    y=++tot;
    if(l==r) {str[y]=v;return;}
    ls[y]=ls[x];
    rs[y]=rs[x];
    int mid=(l+r)>>1;
    if(t<=mid) update(l,mid,ls[x],ls[y],t,v);
    else update(mid+1,r,rs[x],rs[y],t,v); 
}
void ask(int l,int r,int x,int y,int t)
{
    if(l==r) {printf("%c\n",str[y]);return;}
    int mid=(l+r)>>1;
    if(t<=mid) ask(l,mid,ls[x],ls[y],t);
    else ask(mid+1,r,rs[x],rs[y],t);
}
int main()
{
    scanf("%d",&n);
    char opt[5],ch;
    for(int x;n--;)
    {
        scanf("%1s",opt);
        ch=getchar();
        if(opt[0]=='T')
        {
            ch=getchar();
            len[++now]=len[now-1]+1;
            update(1,R,rt[now-1],rt[now],len[now],ch);
        }
        else if(opt[0]=='U')
        {
            scanf("%d",&x);
            len[++now]=len[now-x-1];
            rt[now]=rt[now-x-1];
        }
        else 
        {
            scanf("%d",&x);
            ask(1,R,rt[now-1],rt[now],x);
        }
        ch=getchar();
    }
    return 0;
}

 

posted @ 2017-08-24 11:42  杀猪状元  阅读(199)  评论(0编辑  收藏  举报