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\n", 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\n", Root[Count]->at (x - 1)); } } return 0; }
myj 吊打我Orz,xxy 捆起来打我Orz,myl 文化课上天Orz, lrh 姿势水平敲高Orz, hkd 特别胖Orz%%%,cys 智商感人Orz,syl zz专业Orz,我没有学上, 我们未来一片光明