uva12538 Version Controlled IDE(可持续化Treap * 模板, STL ext/rope(块状链表))
学习:http://www.2cto.com/kf/201401/273863.html
本题是可持续化Treap 的基本题目,虽然可持续化的Treap基本操作不难,但是还没什么深研究,留作模板
可持续化数据结构还是用不好,待深入学习:范浩强谈数据结构
, CLJ的可持久化数据结构研究???
写下注意事项和理解:
(1)指针的使用,在使用之前必须先new()
(2)实现可持续化是Copy()中new()后在复制,若不是先可持续化在可直接复制
(3)注意:Split和Merge的使用
持续更新。。。
本题代码:
#include <iostream> #include <cstdio> #include <cstring> #include <string> #include <cmath> #include <cstdlib> #include <fstream> #include <vector> #include <set> using namespace std; const double eps = 1e-10; const int maxn = 1100000; const int M = 51000; struct node { node* ch[2]; char c; int sz, r; void up() { sz = ch[0]->sz + ch[1]->sz + 1; } }*null; //node t[maxn]; node *root[M]; char s[1100]; int op, pos, num, version; int tot; int m, subt; int step; void newnode(node* &x, char cc = 0) { x = new node(); x->c = cc; x->sz = 1; x->r = rand(); x->ch[0] = x->ch[1] = null; } void copy(node* &x, node* y) { if (y == null) x = y; else newnode(x), *x = *y;///可持久化时,修改操作经过的路径要新建节点 } void merge(node* &o, node* a, node* b) { if (a == null) copy(o, b); else if (b == null) copy(o, a); else if (a->r < b->r) { copy(o, a); merge(o->ch[1], a->ch[1], b); o->up(); } else { copy(o, b); merge(o->ch[0], a, b->ch[0]); o->up(); } } void split(node* o, node* &a, node* &b, int k) { if (!k) { copy(b, o); a = null; } else if (o->sz <= k){ copy(a, o); b = null; } else if (o->ch[0]->sz >= k) { copy(b, o); split(o->ch[0], a, b->ch[0], k); b->up(); } else { copy(a, o); split(o->ch[1], a->ch[1], b, k - o->ch[0]->sz - 1); a->up(); } } void build(node* &o, int l, int r) { if (l > r) return ; int m = (l + r) >> 1; newnode(o, s[m - 1]); build(o->ch[0], l, m - 1); build(o->ch[1], m + 1, r); o->up(); } void out(node *o) { if (o->ch[0] != null) out(o->ch[0]); printf("%c", o->c); if (o->c == ‘c‘) subt++; if (o->ch[1] != null) out(o->ch[1]); } void solve_insert(node* &o, int pos, char s[]) { int n = strlen(s); node *a, *b, *c, *d; build(a, 1, n); split(root[step - 1], b, c, pos); merge(d, b, a); merge(o, d, c); } void solve_delet(node* &o, int pos, int num) { node *a, *b, *c, *d; split(root[step - 1], a, b, pos - 1); split(b, b, c, num);///可同时使用b b??? merge(o, a, c); } void solve_query(int version, int pos, int num) { node *a, *b, *c, *d; split(root[version], a, b, pos - 1); split(b, c, d, num); out(c); puts(""); } void Init() { tot = 0; newnode(null); null->sz = 0; for (int i = 0; i <= m; i++) root[i] = null; } int main() { scanf("%d", &m); Init(); subt = 0; step = 0; while (m--) { scanf("%d", &op); if (op == 1) { scanf("%d", &pos); scanf("%s", s); solve_insert(root[++step], pos - subt, s); } else if (op == 2) { scanf("%d%d", &pos, &num); solve_delet(root[++step], pos - subt, num - subt); } else if (op == 3) { scanf("%d%d%d", &version, &pos, &num); solve_query(version - subt, pos - subt, num - subt); } } }
还有一种STL的解法:
#include <ext/rope>
using namespace __gnu_cxx;
crope t, trp[12], tmp;
具体使用见代码。。。
此STL实现的是块状链表,效率和上面的几乎一样,具体是n*(n^0.5)参考来源:http://www.cnblogs.com/zhsl/archive/2013/05/06/3062000.html
STL。。。
//#pragma warning (disable: 4786) //#pragma comment (linker, "/STACK:16777216") //HEAD #include <cstdio> #include <ctime> #include <cstdlib> #include <cstring> #include <queue> #include <string> #include <set> #include <stack> #include <map> #include <cmath> #include <vector> #include <iostream> #include <algorithm> #include <ext/rope>///!! using namespace __gnu_cxx;///!! using namespace std; typedef long long LL; crope t, trp[50005], tmp;///!! char s[205]; int n, nowv, subt, version; int op, pos, num; int main () { scanf("%d", &n); subt = 0; nowv = 0; while (n--) { scanf("%d", &op); if (op == 1) { scanf("%d%s", &pos, s); pos -= subt; t.insert(pos, s);///在pos后插入串s trp[++nowv] = t; } else if (op == 2) { scanf("%d%d", &pos, &num); pos -= subt; num -= subt; t.erase(pos - 1, num);///删除pos-1后面num个字母 trp[++nowv] = t; } else { scanf("%d%d%d", &version, &pos, &num); version -= subt; pos -= subt; num -= subt; tmp = trp[version].substr(pos - 1, num);///取出pos - 1后面的num个字母 subt += count(tmp.begin(), tmp.end(), ‘c‘);///统计c的个数 cout << tmp << endl;///输出tmp } } return 0; }