C++之路进阶——codevs3333(高级打字机)

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操作。

题解:

   可持久化线段树维护新加入的字符。遇到撤销操作直接转到root[cnt-x-1]的线段树上。

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 #define maxn 2000000
 5 
 6 using namespace std;
 7 
 8 int root[maxn],ls[maxn],rs[maxn],len[maxn],n,x,cnt,tot;
 9 
10 char S[maxn<<1],s[10],ch[10];
11 
12 void update(int &y,int x,int l,int r,int pos,char c)
13     {
14       y=++tot;
15       if (l==r) {S[y]=c;return;}
16       ls[y]=ls[x],rs[y]=rs[x];
17       int mid=(l+r)>>1;
18       if (pos<=mid) update(ls[y],ls[x],l,mid,pos,c);
19           else update(rs[y],rs[x],mid+1,r,pos,c);    
20     }
21 
22 char query(int rt,int l,int r,int pos)
23     {
24          if (l==r) {return S[rt];}
25          int mid=(l+r)>>1;
26          if (pos<=mid) return query(ls[rt],l,mid,pos);
27          if (pos>mid) return query(rs[rt],mid+1,r,pos);
28     }
29 
30 int main()
31    {
32         scanf("%d",&n);
33         for (int i=1;i<=n;i++) 
34            {
35               scanf("%s",s);
36            if (s[0]=='T')
37              {
38                  cnt++;
39                  len[cnt]=len[cnt-1]+1;
40                  scanf("%s",ch);
41                  update(root[cnt],root[cnt-1],1,100000,len[cnt],ch[0]);
42              }
43            if (s[0]=='U')
44              {
45                  scanf("%d",&x);
46                  cnt++;
47                  root[cnt]=root[cnt-x-1];
48                  len[cnt]=len[cnt-x-1];
49              }
50            if (s[0]=='Q')
51              {
52                  scanf("%d",&x);
53                  cout<<query(root[cnt],1,100000,x)<<endl;
54              }                    
55            }
56        return 0;
57    }
原文地址:https://www.cnblogs.com/grhyxzc/p/5738452.html