zoukankan      html  css  js  c++  java
  • uva12538

    可持久化treap

    抄了个模板。

    可持久化treap和主席树一样,都是利用了以前的节点来节省空间。但是却又有些不一样。可持久化treap基于两种操作:merge和split。其他操作都是由这两种操作完成,除了build。这两种操作都要满足第一颗treap的所有节点都是小于第二颗treap,这样才能log合并。

    对于可持久化treap,可以这样理解:每次split,就是找出一颗treap中小于或大于的节点,然后向主席树一样新建一些节点分别连接起来,merge也是用一些新的节点将两颗treap连接起来,这样就起到了可持久化化treap的效果,原来的treap没有改变,只是新加入了一些节点将他们连接起来,又构成了一颗新的treap。

    所以这样空间消耗还是很大的。无论什么操作都要新建节点。

    #include<bits/stdc++.h>
    using namespace std;
    typedef pair<int, int> PII;
    const int N = 5000010;
    int n, delta, cnt, now;
    int size[N], rnd[N], child[N][2], root[N];
    char c[N], s[N];
    void update(int x)
    {
        size[x] = size[child[x][0]] + size[child[x][1]] + 1;
    }
    int newnode(char v)
    {
        ++cnt;
        size[cnt] = 1;
        rnd[cnt] = rand();
        c[cnt] = v;
        return cnt;
    }
    int copy(int a)
    {
        ++cnt;
        child[cnt][0] = child[a][0];
        child[cnt][1] = child[a][1];
        size[cnt] = size[a];
        rnd[cnt] = rnd[a];
        c[cnt] = c[a];
        return cnt;
    }
    int merge(int x, int y)
    {
        if(!x) return y;
        if(!y) return x;
        int z;
        if(rnd[x] < rnd[y])
        {
            z = copy(x);
            child[z][1] = merge(child[z][1], y);
        }
        else
        {
            z = copy(y);
            child[z][0] = merge(x, child[z][0]);
        }
        update(z);
        return z;
    }
    PII split(int x, int k)
    {
        if(!x) return make_pair(0, 0);
        if(k <= size[child[x][0]])
        {
            int z = copy(x);
            PII ret = split(child[x][0], k);
            child[z][0] = ret.second;
            ret.second = z;
            update(z);
            return ret;
        }
        else
        {
            int z = copy(x);
            PII ret = split(child[x][1], k - size[child[x][0]] - 1);
            child[z][1] = ret.first;
            ret.first = z;
            update(z);
            return ret;         
        }
    }
    void build(int &x, int l, int r)
    {
        if(l > r) return;
        int mid = (l + r) >> 1;
        x = newnode(s[mid]);
        build(child[x][0], l, mid - 1);
        build(child[x][1], mid + 1, r);
        update(x);
    }
    void ins(int &x, int last, int pos)
    {
        int a, b, c, len = strlen(s + 1);
        PII t = split(last, pos);
        build(c, 1, len);
        x = merge(merge(t.first, c), t.second);
    }
    void del(int &x, int last, int pos, int len)
    {
        int a, b, c;
        PII t1 = split(last, pos - 1);
        PII t2 = split(t1.second, len);
        x = merge(t1.first, t2.second);
    }
    void print(int x)
    {
        if(!x) return;
        print(child[x][0]);
        printf("%c", c[x]);
        if(c[x] == 'c') ++delta;
        print(child[x][1]);
    }
    void print(int x, int pos, int len)
    {
        PII t1 = split(x, pos - 1);
        PII t2 = split(t1.second, len);
        print(t2.first);
        puts("");
    }
    int main()
    {
        srand(19992147);
        scanf("%d", &n);
        while(n--)
        {
            int opt, pos, len, x; scanf("%d", &opt);
            if(opt == 1)
            {
                scanf("%d%s", &pos, s + 1);
                pos -= delta;
                ins(root[now + 1], root[now], pos);
                ++now;
            }
            if(opt == 2)
            {
                scanf("%d%d", &pos, &len);
                pos -= delta; len -= delta;
                del(root[now + 1], root[now], pos, len);
                ++now;
            }
            if(opt == 3)
            {
                scanf("%d%d%d", &x, &pos, &len);
                x -= delta; pos -= delta; len -=delta; 
                print(root[x], pos, len);
            }
    //        printf("root[%d]=%d
    ", now, root[now]);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    SpringMVC
    Spring mvc 下Ajax获取JSON对象问题 406错误
    Docker国内镜像源
    获取redis cluster主从关系
    终端登录超时限制暂时解除
    vim全选,全部复制,全部删除
    [转]Redis集群搭建
    Jenkins持续集成01—Jenkins服务搭建和部署
    ELK重难点总结和整体优化配置
    ELK 经典用法—企业自定义日志收集切割和mysql模块
  • 原文地址:https://www.cnblogs.com/19992147orz/p/7078314.html
Copyright © 2011-2022 走看看