码迷,mamicode.com
首页 > 其他好文 > 详细

[UVa12538]Version Controlled IDE

时间:2017-12-23 23:09:09      阅读:199      评论:0      收藏:0      [点我收藏+]

标签:持久   air   ++   turn   插入   utc   merge   putchar   span   

题意:维护一个字符串,支持插入字符串,删除连续的一段,查询历史版本的子串,强制在线

本来是用rope可以水过的,但是想拿来试水可持久化treap

几乎跟普通treap完全一样,只不过是merge和split时要相应地复制节点,注意是复制不是直接新建

建树得用笛卡尔树了TT,其实挺好理解的,最后记得全部pushup并退栈就好

决定了!以后写可持久化treap都用指针,挺优秀啊w

p.s.UVa真的太慢啦,机房的辣鸡网络不太兹磁这个网站

srand(time(0))无用论?

#include<stdio.h>
#include<stdlib.h>
struct treap{
	treap*l,*r;
	int siz,fix;
	char c;
	void update(){siz=1+(l?l->siz:0)+(r?r->siz:0);}
	treap(char v){
		c=v;
		fix=rand()*rand();
		l=r=0;
		siz=1;
	}
	treap(treap*t){
		*this=*t;
	}
}*rt[50010],*stk[1000010];
char s[1000010];
int siz(treap*x){return x?x->siz:0;}
treap*build(){
	int top=0,i;
	treap*x,*las;
	for(i=0;s[i];i++){
		x=new treap(s[i]);
		las=0;
		while(top&&stk[top]->fix>x->fix){
			stk[top]->update();
			las=stk[top];
			top--;
		}
		if(top)stk[top]->r=x;
		x->l=las;
		top++;
		stk[top]=x;
	}
	while(top){
		stk[top]->update();
		top--;
	}
	return stk[1];
}
struct pair{
	treap*l,*r;
	pair(treap*a=0,treap*b=0){l=a;r=b;}
};
pair split(treap*x,int k){
	if(x==0)return pair();
	pair s;
	treap*n;
	n=new treap(x);
	if(k<=siz(x->l)){
		s=split(n->l,k);
		n->l=s.r;
		s.r=n;
	}else{
		s=split(n->r,k-siz(x->l)-1);
		n->r=s.l;
		s.l=n;
	}
	n->update();
	return s;
}
treap*merge(treap*a,treap*b){
	if(a==0&&b==0)return 0;
	if(a==0)return new treap(b);
	if(b==0)return new treap(a);
	treap*x;
	if(a->fixfix){
		x=new treap(a);
		x->r=merge(x->r,b);
	}else{
		x=new treap(b);
		x->l=merge(a,x->l);
	}
	x->update();
	return x;
}
int ccnt;
void dfs(treap*x){
	if(x->l)dfs(x->l);
	if(x->c==‘c‘)ccnt++;
	putchar(x->c);
	if(x->r)dfs(x->r);
}
int main(){
	int m,i,x,y,z,cnt;
	pair p,q;
	scanf("%d",&m);
	cnt=0;
	while(m--){
		scanf("%d",&i);
		if(i==1){
			scanf("%d%s",&x,s);
			x-=ccnt;
			p=split(rt[cnt],x);
			cnt++;
			rt[cnt]=merge(p.l,merge(build(),p.r));
		}
		if(i==2){
			scanf("%d%d",&x,&y);
			x-=ccnt;
			y-=ccnt;
			p=split(rt[cnt],x-1);
			q=split(p.r,y);
			cnt++;
			rt[cnt]=merge(p.l,q.r);
		}
		if(i==3){
			scanf("%d%d%d",&x,&y,&z);
			x-=ccnt;
			y-=ccnt;
			z-=ccnt;
			p=split(rt[x],y-1);
			q=split(p.r,z);
			dfs(q.l);
			putchar(‘\n‘);
		}
	}
}

[UVa12538]Version Controlled IDE

标签:持久   air   ++   turn   插入   utc   merge   putchar   span   

原文地址:http://www.cnblogs.com/jefflyy/p/8094514.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!