UVA 12538 Version Controlled IDE 可持久化平衡树 || rope

来源:互联网 发布:数据分析职业发展 知乎 编辑:程序博客网 时间:2024/05/20 12:51

题目:

https://vjudge.net/problem/UVA-12538

题意:

模拟一个版本控制编辑器,有以下操作:

  • 1 p s: 在p后面位置插入一个字符串s
  • 2 p c:从第p个字符开始删掉c个字符
  • 3 v p c:在第v个版本中,从第p个位置开始取c个字符并输出
    前两种操作中每个操作后形成一个新版本。为防止预处理,要求输入中的v p c都要先减去dd是之前所有的第三种操作中字符c的个数

思路:

在线询问某个版本的具体情况, 显然是要可持久化的,可以用非旋转treap实现,这里先用rope实现。。。过两天填可持久化平衡树的坑。。。

#include <bits/stdc++.h>#include <ext/rope>using namespace std;using namespace __gnu_cxx;const int N = 50000 + 10;char str[N];crope rs, his[N];int main(){    int n, opt, v, p, len;    int num = 0, cur = 0;    scanf("%d", &n);    while(n--)    {        scanf("%d", &opt);        if(opt == 1)        {            scanf("%d%s", &p, str);            p -= num;            rs.insert(p, str);            his[++cur] = rs;        }        else if(opt == 2)        {            scanf("%d%d", &p, &len);            p -= num, len -= num;            rs.erase(p-1, len);            his[++cur] = rs;        }        else if(opt == 3)        {            scanf("%d%d%d", &v, &p, &len);            v -= num, p -= num, len -= num;            string s = his[v].substr(p-1, len).c_str();            num += count(s.begin(), s.end(), 'c');            printf("%s\n", s.c_str());//            crope tp = his[v].substr(p-1, len);//            num += count(tp.begin(), tp.end(), 'c');//            cout << tp << endl;//            printf("%s\n", tp.c_str());        }    }    return 0;}
//2017.9.27//可持久化treap类似于可持久化线段树,原本的形态保持不变,通过新增节点的方式进行merge和split操作,很机智。。。#include <bits/stdc++.h>using namespace std;typedef pair<int, int> proot;const int N = 4000000 + 10, M = 50000 + 10, INF = 0x3f3f3f3f;struct node{    int l, r, val, pri, sz;    void init(int _val, int _pri, int _sz)    {        val = _val, pri = _pri, sz = _sz;        l = r = 0;    }}tr[N];char s[M];int root[M];int tot, num;void init(){    tot = 0;    tr[0].init(0, 0, 0);}int new_node(int val){    tr[++tot].init(val, rand(), 1);    return tot;}void update(int x){    tr[x].sz = 1 + tr[tr[x].l].sz + tr[tr[x].r].sz;}int Copy(int x){    tr[++tot] = tr[x];    return tot;}int Merge(int x, int y){    if(!x || !y) return x + y;    int z;    if(tr[x].pri < tr[y].pri)    {        z = Copy(x);        tr[z].r = Merge(tr[z].r, y);    }    else    {        z = Copy(y);        tr[z].l = Merge(x, tr[z].l);    }    update(z);    return z;}proot split(int x, int k){    //if(!k) return proot(0, x);    if(!x) return proot(0, 0);    proot y;    if(k <= tr[tr[x].l].sz)    {        int z = Copy(x);        y = split(tr[x].l, k);        tr[z].l = y.second;        y.second = z;        update(z);    }    else    {        int z = Copy(x);        y = split(tr[x].r, k - tr[tr[x].l].sz - 1);        tr[z].r = y.first;        y.first = z;        update(z);    }    return y;}void build(int &x, int l, int r){    if(l > r) return;    int mid = (l + r) >> 1;    x = new_node(s[mid]);    build(tr[x].l, l, mid-1);    build(tr[x].r, mid+1, r);    update(x);}void Insert(int &x, int last, int pos){    int len = strlen(s + 1);    proot y = split(last, pos);    build(x, 1, len);    x = Merge(Merge(y.first, x), y.second);}void del(int &x, int last, int pos, int len){    proot t1 = split(last, pos-1);    proot t2 = split(t1.second, len);    x = Merge(t1.first, t2.second);}void print(int x){    if(!x) return;    print(tr[x].l);    printf("%c", (char)tr[x].val);    if(tr[x].val == 'c') ++num;    print(tr[x].r);}void print(int x, int pos, int len){    proot t1 = split(x, pos-1);    proot t2 = split(t1.second, len);    print(t2.first);    printf("\n");}int main(){    srand((unsigned)time(NULL));    int n, opt, v, p, len, cur = 0;    init();    num = 0;    scanf("%d", &n);    while(n--)    {        scanf("%d", &opt);        if(opt == 1)        {            scanf("%d%s", &p, s+1);            p -= num;            Insert(root[cur+1], root[cur], p);            ++cur;        }        else if(opt == 2)        {            scanf("%d%d", &p, &len);            p -= num, len -= num;            del(root[cur+1], root[cur], p, len);            ++cur;        }        else if(opt == 3)        {            scanf("%d%d%d", &v, &p, &len);            v -= num, p -= num, len -= num;            print(root[v], p, len);        }    }    return 0;}
阅读全文
0 0
原创粉丝点击