标签:val class vector mes build nlog 修改 字母 undo
早苗入手了最新的高级打字机。最新款自然有着与以往不同的功能,那就是它具备撤销功能,厉害吧。
请为这种高级打字机设计一个程序,支持如下3种操作:
1.T x:在文章末尾打下一个小写字母x。(type操作)
2.U x:撤销最后的x次修改操作。(Undo操作)
(注意Query操作并不算修改操作)
3.Q x:询问当前文章中第x个字母并输出。(Query操作)
文章一开始可以视为空串。
第1行:一个整数n,表示操作数量。
以下n行,每行一个命令。保证输入的命令合法。
7 T a T b T c Q 2 U 2 T c Q 2
b c
【数据范围】
对于40%的数据 n<=200;
对于100%的数据 n<=100000;保证Undo操作不会撤销Undo操作。
<高级挑战>
对于200%的数据 n<=100000;Undo操作可以撤销Undo操作。
必须使用在线算法完成该题。
#include <iostream>
#include <cstdio>
#define N 100005
using namespace std;
struct T {int l,r,v;}t[N*32];
int n,dfn,dex;
int cnt[N],rt[N];
int build(int l,int r)
{
int p=++dex,mid=l+r>>1;
if(l==r) return p;
t[p].l=build(l,mid);
t[p].r=build(mid+1,r);
return p;
}
int upd(int lat,int l,int r,int pos,int val)
{
int p=++dex,mid=l+r>>1;
t[p]=t[lat];
if(l==r) {t[p].v=val;return p;}
if(pos<=mid) t[p].l=upd(t[lat].l,l,mid,pos,val);
else t[p].r=upd(t[lat].r,mid+1,r,pos,val);
return p;
}
int ask(int p,int l,int r,int pos)
{
if(l==r) return t[p].v;
int mid=l+r>>1;
if(pos<=mid) return ask(t[p].l,l,mid,pos);
return ask(t[p].r,mid+1,r,pos);
}
int main()
{
cin>>n;
rt[0]=build(1,n);
for(int i=1;i<=n;i++)
{
char c[3]; scanf("%s",c);
if(c[0]=='T') {
char x[3]; scanf("%s",x);
dfn++,rt[dfn]=upd(rt[dfn-1],1,n,cnt[dfn-1]+1,x[0]-'a'+1);
cnt[dfn]=cnt[dfn-1]+1;
}
else if(c[0]=='U') {
int x; scanf("%d",&x);
dfn++,rt[dfn]=rt[dfn-x-1];
cnt[dfn]=cnt[dfn-x-1];
}
else if(c[0]=='Q') {
int x; scanf("%d",&x);
printf("%c\n",ask(rt[dfn],1,n,x)-1+'a');
}
}
return 0;
}
标签:val class vector mes build nlog 修改 字母 undo
原文地址:https://www.cnblogs.com/BigYellowDog/p/11832721.html