撤销操作如果新开一个版本重建根节点就能过,但是直接覆盖就会超空间。这两个的区别在哪?
全部代码
#define N 100010
#define ll long long
#include<bits/stdc++.h>
using namespace std;
int n;
struct node{
int ls,rs;char val;
}tr[N<<4];
int root[N];
int cnt,top,len[N];
int clone(int p){ tr[++top]=tr[p];return top;}
int update(int p,int l,int r,int x,char g);
char query(int p,int l,int r,int x);
int main(){
scanf("%d",&n);
for(int i=1;i<=n;++i){
char op;
cin>>op;
if(op=='T'){
char x;cin>>x;
++cnt;
len[cnt]=len[cnt-1]+1;
root[cnt]=update(root[cnt-1],1,n,len[cnt],x);
}
else if(op=='U'){
int x;cin>>x;
++cnt;
root[cnt]=root[cnt-1-x];len[cnt]=len[cnt-1-x];
}
else{
int x;cin>>x;
printf("%c\n", query(root[cnt],1,n,x) );
}
}
return 0;
}
char query(int p,int l,int r,int x){
int mid=(l+r)>>1;
if(l==x&&r==x) {
return tr[p].val;
}
if(x<=mid) return query(tr[p].ls,l,mid,x);
else return query(tr[p].rs,mid+1,r,x);
}
int update(int p,int l,int r,int x,char g){
p=clone(p);
if(l==x&&r==x){
tr[p].val=g;
return p;
}
int mid=(l+r)>>1;
if(x<=mid) tr[p].ls=update(tr[p].ls,l,mid,x,g);
else tr[p].rs=update(tr[p].rs,mid+1,r,x,g);
return p;
}
有疑问的两个部分代码
else if(op=='U'){
int x;cin>>x;
++cnt;
root[cnt]=root[cnt-1-x];
len[cnt]=len[cnt-1-x];
}
else if(op=='U'){
int x;cin>>x;
cnt-=x;len-=x;
}