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

 

你可能感兴趣的:(version)