题目描述
早苗入手了最新的高级打字机。最新款自然有着与以往不同的功能,那就是它具备撤销功能,厉害吧。
请为这种高级打字机设计一个程序,支持如下3种操作:
1.T x:在文章末尾打下一个小写字母x。(type操作)
2.U x:撤销最后的x次修改操作。(Undo操作)
(注意Query操作并不算修改操作)
3.Q x:询问当前文章中第x个字母并输出。(Query操作)
文章一开始可以视为空串。
输入格式
第1行:一个整数n,表示操作数量。
以下n行,每行一个命令。保证输入的命令合法。
输出格式
每行输出一个字母,表示Query操作的答案。
输入输出样例
输入 #1
7 T a T b T c Q 2 U 2 T c Q 2
输出 #1
View Code
b c
这题一定要建树(我之前都懒得建树了。。)
// luogu-judger-enable-o2 #include<bits/stdc++.h> using namespace std; //input by bxd #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define repp(i,a,b) for(int i=(a);i>=(b);--i) #define ll long long #define see(x) (cerr<<(#x)<<'='<<(x)<<endl) #define pb push_back #define inf 0x3f3f3f3f #define CLR(A,v) memset(A,v,sizeof A) typedef pair<int,int>pii; ////////////////////////////////// const int N=2e6+10; int T[N<<5],lson[N<<5],rson[N<<5],t[N<<5],ncnt; void build(int l,int r,int &pos) { pos=++ncnt; if(l==r)return ; int m=(l+r)>>1; build(l,m,lson[pos]); build(m+1,r,rson[pos]); } void up(int x,int v,int l,int r,int pre,int &pos) { pos=++ncnt; lson[pos]=lson[pre]; rson[pos]=rson[pre]; if(l==r){t[pos]=v;return ;} int m=(l+r)>>1; if(x<=m)up(x,v,l,m,lson[pre],lson[pos]); else up(x,v,m+1,r,rson[pre],rson[pos]); } int qsum(int k,int l,int r,int pos) { if(l==r)return t[pos]; int m=(l+r)>>1; if(k<=m)return qsum(k,l,m,lson[pos]); else return qsum(k,m+1,r,rson[pos]); } char s[2],ss; int n,x,rt,len[N]; int main() { scanf("%d",&n); build(1,100005,T[0]); int x; rep(i,1,n) { scanf("%s",s); if(s[0]=='T') { cin>>ss; rt++;len[rt]=len[rt-1]+1; up(len[rt],(int)ss,1,100005,T[rt-1],T[rt]); } else if(s[0]=='Q') { cin>>x; printf("%c ",(char)qsum(x,1,100005,T[rt])); } else { cin>>x;rt++; T[rt]=T[rt-x-1]; len[rt]=len[rt-x-1]; } } return 0; }