UVALive 6145 Version Controlled IDE(可持久化treap、rope)

题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4156

题目拷贝难度大我就不复制了。

 

题目大意:维护一个字符串,要求支持插入、删除操作,还有输出第 i 次操作后的某个子串。强制在线。

思路1:使用可持久化treap可破,详细可见CLJ的《可持久化数据结构的研究》。

思路2:rope大法好,详见:http://blog.csdn.net/guognib/article/details/20563453(文档:http://www.sgi.com/tech/stl/Rope.html),代码短速度快,可惜不能打lazy标记。

PS:自从学了函数式编程,发现可持久化什么的都变简单了。

PS:不用智能指针只要845MS。这真是一个大坑。本来我换成普通指针只是想用于调试……

PS:UVALive居然不保存代码!于是我又去vjudge交了一次。

 

代码(C++11 2116MS):

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 
  4 struct Node;
  5 typedef shared_ptr<Node> Nptr;
  6 //typedef Node* Nptr;
  7 
  8 struct Node {
  9     Nptr lson, rson;
 10     int size, weight;
 11     char c;
 12     void update() {
 13         size = lson->size + rson->size + 1;
 14     }
 15 };
 16 Nptr nil;
 17 
 18 Nptr new_node(char c) {
 19     Nptr x = Nptr(new Node);
 20     x->lson = x->rson = nil;
 21     x->size = 1;
 22     x->weight = rand();
 23     x->c = c;
 24     return x;
 25 }
 26 
 27 Nptr new_node(char c, Nptr lson, Nptr rson) {
 28     Nptr x = Nptr(new Node);
 29     x->lson = lson;
 30     x->rson = rson;
 31     x->update();
 32     x->weight = rand();
 33     x->c = c;
 34     return x;
 35 }
 36 
 37 void initTreap() {
 38     nil = Nptr(new Node);
 39     nil->lson = nil->rson = nil;
 40     nil->size = 0;
 41 }
 42 
 43 Nptr build(char *st, char *ed) {
 44     if(st == ed) return nil;
 45     assert(st < ed);
 46     char *mid = st + (ed - st) / 2;
 47     return new_node(*mid, build(st, mid), build(mid + 1, ed));
 48 }
 49 
 50 typedef pair<Nptr, Nptr> Ppp;
 51 
 52 Ppp split(Nptr x, int n) {
 53     if(n == 0) return make_pair(nil, x);
 54     int ls = x->lson->size;
 55 
 56     if(ls >= n) {
 57         Ppp a = split(x->lson, n);
 58         return make_pair(a.first, new_node(x->c, a.second, x->rson));
 59     } else {
 60         Ppp a = split(x->rson, n - ls - 1);
 61         return make_pair(new_node(x->c, x->lson, a.first), a.second);
 62     }
 63 }
 64 
 65 Nptr merge(Nptr a, Nptr b) {
 66     if(a == nil) return b;
 67     if(b == nil) return a;
 68     if(a->weight < b->weight) {
 69         return new_node(a->c, a->lson, merge(a->rson, b));
 70     } else {
 71         return new_node(b->c, merge(a, b->lson), b->rson);
 72     }
 73 }
 74 
 75 int print(Nptr x) {
 76     if(x == nil) return 0;
 77     int res = (x->c == 'c');
 78     res += print(x->lson);
 79     putchar(x->c);
 80     res += print(x->rson);
 81     return res;
 82 }
 83 
 84 Nptr insert(Nptr x, int pos, char s[]) {
 85     Nptr a = build(s, s + strlen(s));
 86     Ppp p = split(x, pos);
 87     return merge(p.first, merge(a, p.second));
 88 }
 89 
 90 Nptr remove(Nptr x, int pos, int len) {
 91     Ppp a = split(x, pos);
 92     Ppp b = split(a.second, len);
 93     return merge(a.first, b.second);
 94 }
 95 
 96 int print(Nptr x, int pos, int len) {
 97     Ppp a = split(x, pos);
 98     Ppp b = split(a.second, len);
 99     int res = print(b.first);
100     puts("");
101     return res;
102 }
103 
104 Nptr rt[50010];
105 char s[110];
106 int n, d, vnow;
107 
108 int main() {
109     initTreap();
110     rt[0] = nil;
111 
112     scanf("%d", &n);
113     while(n--) {
114         int v, p, c, op;
115         scanf("%d", &op);
116         if(op == 1) {
117             scanf("%d%s", &p, s);
118             p -= d;
119             vnow++;
120             rt[vnow] = insert(rt[vnow - 1], p, s);
121         }
122         if(op == 2) {
123             scanf("%d%d", &p, &c);
124             p -= d, c -= d;
125             vnow++;
126             rt[vnow] = remove(rt[vnow - 1], p - 1, c);
127         }
128         if(op == 3) {
129             scanf("%d%d%d", &v, &p, &c);
130             v -= d, p -= d, c -= d;
131             d += print(rt[v], p - 1, c);
132         }
133     }
134 }
View Code

 

代码(rope大法 322MS):

 1 #include <bits/stdc++.h>
 2 #include <ext/rope>
 3 using namespace std;
 4 #define FOR(i, n) for(int i = 0; i < n; ++i)
 5 
 6 const int MAXN = 50010;
 7 const int MAXS = 200010;
 8 
 9 __gnu_cxx::crope rt[MAXN], tmp;
10 
11 char s[MAXS];
12 int m, vnow, d;
13 
14 int main() {
15     scanf("%d", &m);
16     while(m--) {
17         int op, p, v, c;
18         scanf("%d", &op);
19         if(op == 1) {
20             scanf("%d%s", &p, s);
21             p -= d;
22             rt[vnow + 1] = rt[vnow];
23             rt[++vnow].insert(p, s);
24         } else if(op == 2) {
25             scanf("%d%d", &p, &c);
26             p -= d, c -= d;
27             rt[vnow + 1] = rt[vnow];
28             rt[++vnow].erase(p - 1, c);
29         } else if(op == 3) {
30             scanf("%d%d%d", &v, &p, &c);
31             v -= d, p -= d, c -= d;
32             tmp = rt[v].substr(p - 1, c);
33             printf("%s\n", tmp.c_str());
34             d += count(tmp.begin(), tmp.end(), 'c');
35         }
36     }
37 }
View Code

 

posted @ 2015-02-02 23:50  Oyking  阅读(396)  评论(0编辑  收藏  举报