[UVa12538]Version Controlled IDE
阿新 • • 發佈:2017-12-24
main 新建 uva 優秀 直接 merge shu imu dfs
題意:維護一個字符串,支持插入字符串,刪除連續的一段,查詢歷史版本的子串,強制在線
本來是用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