Evanyou Blog 彩带

UVA12538 Version Controlled IDE

 

题意翻译

维护一种数据结构,资磁三种操作。

1.在p位置插入一个字符串s

2.从p位置开始删除长度为c的字符串

3.输出第v个历史版本中从p位置开始的长度为c的字符串

1n50000,所有字符串总长度小于等于106,输出字符串总长度小于等于20000

强制在线,每次输入中的数字都要减去你的所有输出中字母c的个数

Translated by @litble

题目描述

PDF

输入输出格式

输入格式:

 

 

输出格式:

 

 

输入输出样例

输入样例#1: 
6
1 0 abcdefgh
2 4 3
3 1 2 5
3 3 3 4
1 4 xy
3 5 4 6
输出样例#1: 
bcdef
bcg
bxyc

 

 

 

Solution:

  本题可持久化平衡树裸题,画风和神犇CLJ的可持久化数据结构研究中的最后一题超级编辑器,貌似没啥区别。

  我们用可持久化平衡树维护字符串的中序遍历,对于各操作:

    1、在上一版本的某一位置加入一段字符串:对加入的字符串中序遍历建树(因为treap的随机值原因,树根不一定是$\frac{1+n}{2}$,这里我骚操作每个节点的键值都加上父亲的键值以保证树的形态),然后将原版本的树以插入位置split,再二次merge。

    2、删除上一版本的某一位置开始的一段长度的字符串:先split出这段区间,然后merge左右子树。

    3、输出某一版本的某一位置开始的一段长度的字符串:先split出这段区间,然后中序遍历这段区间。

  注意本题强制在线需要统计输出的字符$c$的个数。

代码:

/*Code by 520 -- 9.27*/
#include<bits/stdc++.h>
#define il inline
#define ll long long
#define RE register
#define For(i,a,b) for(RE int (i)=(a);(i)<=(b);(i)++)
#define Bor(i,a,b) for(RE int (i)=(b);(i)>=(a);(i)--)
using namespace std;
const int N=8000005;
int n,cnt,now,tc,root[50005];
struct node{
    int ls,rs,date,siz,rnd;
}t[N];
char s[150];

int newnode(int v){
    ++cnt;
    t[cnt].date=v,t[cnt].siz=1,t[cnt].rnd=rand()%30000000;
    return cnt;
}

il void up(int rt){t[rt].siz=t[t[rt].ls].siz+t[t[rt].rs].siz+1;}

int merge(int x,int y){
    if(!x||!y) return x+y;
    if(t[x].rnd<t[y].rnd){
        int p=++cnt;t[p]=t[x];
        t[p].rs=merge(t[p].rs,y);
        up(p);
        return p;
    }
    else {
        int p=++cnt;t[p]=t[y];
        t[p].ls=merge(x,t[p].ls);
        up(p);
        return p;
    }
}

void split(int rt,int k,int &x,int &y){
    if(!rt) {x=0,y=0;return;}
    if(t[t[rt].ls].siz<k) {
        x=++cnt;t[x]=t[rt];
        split(t[x].rs,k-t[t[rt].ls].siz-1,t[x].rs,y);
        up(x);
    }
    else {
        y=++cnt;t[y]=t[rt];
        split(t[y].ls,k,x,t[y].ls);
        up(y);
    }
}

int build(int l,int r,int lst) {
    if(l>r) return 0;
    int m=l+r>>1,rt=newnode(s[m]);
    t[rt].rnd+=lst;
    t[rt].ls=build(l,m-1,t[rt].rnd),t[rt].rs=build(m+1,r,t[rt].rnd);
    up(rt);
    return rt;
}

void print(int rt){
    if(!rt) return;
    print(t[rt].ls);
    putchar(t[rt].date);
    if(t[rt].date=='c') tc++;
    print(t[rt].rs);
}

int main(){
    int opt,p,q,v,x,y,z,rt;
    while(scanf("%d",&n)!=EOF){
        while(n--){
            scanf("%d",&opt);
            if(opt==1){
                scanf("%d%s",&p,s+1);
                rt=build(1,strlen(s+1),0);
                p-=tc,++now;
                if(!p) root[now]=merge(rt,root[now-1]);
                else if(p==t[root[now-1]].siz) root[now]=merge(root[now-1],rt);
                else {
                    x=y=0; split(root[now-1],p,x,y);
                    root[now]=merge(x,rt),root[now]=merge(root[now],y);
                }
            }
            else if(opt==2){
                ++now;
                scanf("%d%d",&p,&q),p-=tc,q-=tc;
                x=y=z=0;
                split(root[now-1],p-1,x,y),split(y,q,y,z);
                root[now]=merge(x,z);
            }
            else {
                scanf("%d%d%d",&v,&p,&q),v-=tc,p-=tc,q-=tc;
                x=y=z=0;
                split(root[v],p-1,x,y),split(y,q,y,z);
                print(y),putchar('\n');
            }
        }
        tc=cnt=now=0;memset(root,0,sizeof(root));
    }
    return 0;
}

 

posted @ 2018-09-29 09:27  five20  阅读(169)  评论(0编辑  收藏  举报
Live2D