【COGS】 [HZOI 2015] Persistable Editor-可持久化平衡树

传送门:cogs2314


题解

非旋treap的模板题。把字符串的信息按输入顺序记在treap上,每个节点存一个字符。插入字符串和输出都直接暴力找(长度保证)


代码

#include
using namespace std;
const int N=1e5+1000;
int rt[N],tim,cnt;
int n,op,ix,iy,iz,len,D;
char s[255];
 
namespace bst{
   #define ls t[x].lc
   #define rs t[x].rc
   #define mid (((l)+(r))>>1)
   
   struct node{
   	int lc,rc,ss,rd;char c;
   	node(){}
   	node(int L,int R,int S,int RR,char C){lc=L,rc=R,ss=S,rd=RR,c=C;}
   }t[N*50];
   
   inline void pushup(int x){t[x].ss=t[ls].ss+t[rs].ss+1;}
   inline int newnode(char v){t[++cnt]=node(0,0,1,rand(),v);return cnt;}
   inline int copynode(int v){t[++cnt]=t[v];return cnt;}
   
   inline void split(int nx,int k,int &x,int &y)
   {
   	  if(!nx) {x=y=0;return;}
   	  if(t[t[nx].lc].ss>=k) {y=copynode(nx);split(t[y].lc,k,x,t[y].lc);pushup(y);}
   	  else {x=copynode(nx);split(rs,k-t[ls].ss-1,rs,y);pushup(x);}
   }
   
   inline int merge(int x,int y)
   {
   	   if(!x || !y) return x+y;
   	   int z;
   	   if(t[x].rd<t[y].rd) {z=copynode(x);t[z].rc=merge(t[z].rc,y);}
   	   else{z=copynode(y);t[z].lc=merge(x,t[z].lc);}
   	   pushup(z);return z;
   }
   
   inline void out(int x)
   {
   	   if(!x) return;
   	   out(ls);
	   putchar(t[x].c);if(t[x].c=='c') D++;
	   out(rs);
   }
   
   inline void print(int nx)
   {
   	   int x,y,z,q;
   	   split(nx,ix-1,x,y);
   	   split(y,iy,z,q);
   	   out(z);
   	   y=merge(z,q);merge(x,y);
   	   puts("");
   }
   
   inline void build(int &x,int l,int r)
   {
   	  if(l>r) return;
	  x=newnode(s[mid]);
   	  build(ls,l,mid-1);build(rs,mid+1,r);
   	  pushup(x);
   }
 
   inline void insert(int &nx)
   {
   	  int x,y,z;
   	  split(nx,ix,x,y);
   	  build(z,1,len);
   	  nx=merge(merge(x,z),y);
   }
   
   inline void del(int &nx)
   {
   	  int x,y,z,q;
   	  split(nx,ix-1,x,y);
   	  split(y,iy,z,q);
   	  nx=merge(x,q);
   }
   
  
}
 
using namespace bst;
int main(){
	freopen("persistable_editor.in","r",stdin);
	freopen("persistable_editor.out","w",stdout);
	scanf("%d",&n);
	while(n--){
		scanf("%d%d",&op,&ix);
		ix-=D;
		if(op==1){
			scanf("%s",s+1);
			len=strlen(s+1);
			tim++;rt[tim]=rt[tim-1];
			insert(rt[tim]);
		}else if(op==2){
			scanf("%d",&iy);iy-=D;
			tim++;rt[tim]=rt[tim-1];
			del(rt[tim]);
		}else{
			scanf("%d%d",&iz,&iy);iy-=D;iz-=D;
			swap(ix,iz);print(rt[iz]);
		}
	}
}

你可能感兴趣的:(平衡树)