codevs 3333 高级打字机

二次联通门 : codevs 3333 高级打字机

知道了神奇的处理字符串的可持久化平衡树...

#include <ext/rope>

然而并不是很会用, 于是写的是主席树

/*
    codevs 3333 高级打字机
    
    
    可持久化线段树
    
    其实我第一眼看到这个题时以为是可持久化平衡树...
     
    T操作和 Q操作没话说
    
    裸的修改与查询
    只是对于撤销操作
    一开始想复杂了
    
    后来写了写后发现, 其实撤销一个
    不就是相当于新建一个撤销之前的版本吗...
    
    直接把复制前版本的根节点的指针复制到新版本上去...
    然后1遍AC..
     
*/
#include <cstdio>

#define Max 100002

void read (int &now)
{
    now = 0;
    register char word = getchar ();
    while (word < '0' || word > '9')
        word = getchar ();
    while (word >= '0' && word <= '9')
    {
        now = now * 10 + word - '0';
        word = getchar ();
    }
}

struct Segment_Tree_Data 
{
    int Left, Right;
    
    char key;
    
};

Segment_Tree_Data tree[Max << 5];

int Root[Max];

class Lasting_Segment_Tree_Type
{
    private :
        
        int Tree_Count;
        
    public :
        
        void Build (int &now, int l, int r)
        {
            now = ++Tree_Count;
            if (l == r)
                return ;
            register int Mid = l + r >> 1;
            Build (tree[now].Left, l, Mid);
            Build (tree[now].Right, Mid + 1, r);
        }
        
        void Updata (int Last, int &now, int l, int r, int pos, char to)
        {
            now = ++Tree_Count;
            if (l == r)
            {
                tree[now].key = to;
                return ;
            }
            register int Mid = l + r >> 1;
            if (pos <= Mid)
            {
                tree[now].Right = tree[Last].Right;
                Updata (tree[Last].Left, tree[now].Left, l, Mid, pos, to);
            }
            else
            {
                tree[now].Left = tree[Last].Left;
                Updata (tree[Last].Right, tree[now].Right, Mid + 1, r, pos, to);
            }
        }
    
        void Query (int now, int l, int r, int pos)
        {
            if (l == r)
            {
                printf ("%c
", tree[now].key);
                return ;
            }
            register int Mid = l + r >> 1;
            if (pos <= Mid)
                Query (tree[now].Left, l, Mid, pos);
            else
                Query (tree[now].Right, Mid + 1, r, pos);
        }
        
};

Lasting_Segment_Tree_Type Tree;

int N;
int length[Max];

int main (int argc, char *argv[])
{
    char type[3];
    int x;
    Tree.Build (Root[0], 1, Max);
    int Count = 0;
    for (read (N); N--;)
    {
        scanf ("%s", type);
        if (type[0] == 'T')
        {
            scanf ("%s", type);
            Count++;
            length[Count] = length[Count - 1] + 1;
            Tree.Updata (Root[Count - 1], Root[Count], 1, Max, length[Count], type[0]);
        }
        else if (type[0] == 'U')
        {
            read (x);
            Count++;
            Root[Count] = Root[Count - x - 1];
            length[Count] = length[Count - x - 1];
        }
        else
        {
            read (x);
            Tree.Query (Root[Count], 1, Max, x);
        }
    }
    return 0;
}

下面就是那个神奇的rope了....

/*
    codevs 3333 高级打字机
    
    库里的可持久化平衡树...
    
    支持各种字符的处理....
    
    思路和主席树基本类似 
    从 shenben 学长那里学的 
*/
#include <iostream>
#include <cstdio>
#include <ext/rope>

#define Max 500006

void read (int &now)
{
    now = 0;
    register char word = getchar ();
    while (word < '0' || word > '9')
        word = getchar ();
    while (word >= '0' && word <= '9')
    {
        now = now * 10 + word - '0';
        word = getchar ();
    }
}

__gnu_cxx :: rope <char> *Root[Max];

int N;

int main (int argc, char *argv[])
{
    int Count = 0;
    char word[5];
    int x;
    Root[0] = new __gnu_cxx :: rope <char> ();
    for (read (N); N--; )
    {
        scanf ("%s", word);
        if (word[0] == 'T')
        {
            scanf ("%s", word);
            Count++;
            Root[Count] = new __gnu_cxx :: rope <char> (*Root[Count - 1]);
            Root[Count]->push_back (word[0]);
        }
        else if (word[0] == 'U')
        {
            read (x);
            Count++;
            Root[Count] = new __gnu_cxx :: rope <char> (*Root[Count - x - 1]);
        }
        else 
        {
            read (x);
            printf ("%c
", Root[Count]->at (x - 1));
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/ZlycerQan/p/6941049.html