UVA 12538 Version Controlled IDE(可持久化treap)
2015-05-29 11:50
375 查看
题意:给定一个字符串,要求支持3种操作:
1:版本+1,当前版本某个位置插入一个字符串;
2:版本+1,删除当前版本某段字符串;
3:询问以前版本的某段字符串。
强制在线。
思路:可持久化treap。。。
贴下模板。。
1:版本+1,当前版本某个位置插入一个字符串;
2:版本+1,删除当前版本某段字符串;
3:询问以前版本的某段字符串。
强制在线。
思路:可持久化treap。。。
贴下模板。。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define N 7000020 int ch [2], rd , val , s ; int tot; int copy(int i) { int k = ++tot; ch[k][0] = ch[i][0]; ch[k][1] = ch[i][1]; rd[k] = rd[i]; val[k] = val[i]; s[k] = 1; return k; } void push_up(int x) { s[x] = s[ch[x][0]] + s[ch[x][1]] + 1; } int merge(int x, int y) { if(x == 0) return y; if(y == 0) return x; if(rd[x] < rd[y]) { int k = copy(x); ch[k][1] = merge(ch[x][1], y); push_up(k); return k; } else { int k = copy(y); ch[k][0] = merge(x, ch[y][0]); push_up(k); return k; } } void split(int x, int k, int &L, int &R) { if(s[x] <= k) { L = x, R = 0; return; } int tmp = s[ch[x][0]]; int t = copy(x); int a, b; if(k <= tmp) { split(ch[x][0], k, a, b); ch[t][0] = b; R = t; L = a; } else { split(ch[x][1], k - tmp - 1, a, b); ch[t][1] = a; L = t; R = b; } push_up(t); } int q, ccnt; int now, root[50020]; char str[120]; int build(int l, int r, int pre) { if(l > r) return 0; int m = (l + r) / 2; int x = ++tot; rd[x] = rand() + pre; s[x] = 1; val[x] = str[m]; ch[x][0] = build(l, m - 1, rd[x]); ch[x][1] = build(m + 1, r, rd[x]); push_up(x); return x; } void out(int x) { if(x == 0) return; out(ch[x][0]); putchar(val[x]); if(val[x] == 'c') ++ccnt; out(ch[x][1]); } int main() { //freopen("tt.txt", "r", stdin); while(scanf("%d", &q) != EOF) { ccnt = 0; tot = 0; now = 0; memset(root, 0, sizeof root); while(q--) { int op; scanf("%d", &op); if(op == 1) { int p; scanf("%d%s", &p, str + 1); int t = build(1, strlen(str + 1), 0); p -= ccnt; ++now; if(p == 0) { root[now] = merge(t, root[now-1]); } else if(p == s[root[now-1]]) root[now] = merge(root[now-1], t); else { int L, R; split(root[now-1], p, L, R); root[now] = merge(L, t); root[now] = merge(root[now], R); } } else if(op == 2) { ++now; int p, c; scanf("%d%d", &p, &c); p -= ccnt, c -= ccnt; int L, R, X, Y; split(root[now-1], p - 1, L, R); split(R, c, X, Y); root[now] = merge(L, Y); } else { int v, p, c; scanf("%d%d%d", &v, &p, &c); v -= ccnt, p -= ccnt, c -= ccnt; int L, R, X, Y; split(root[v], p - 1, L, R); split(R, c, X, Y); out(X); puts(""); } } } return 0; }
相关文章推荐
- HDU ACM 2489 Minimal Ratio Tree
- P124第45题
- Java编码规范
- linux 修改时区
- Code First 数据注释--DatabaseGenerated
- MySQL视图的使用
- UISearchDisplayController的searchResultsTableView的Contentsize不正确的问题
- 部署Physical Dataguard 与 双节点Oracle RAC环境
- 48. C# -- 事件
- MySQL视图的使用
- 微信开发 PC搭建服务器 开发 微信公众号【Java版本】
- 非常全面的SQL Server巡检脚本来自sqlskills团队的Glenn Berry 大牛
- Linux定时任务Crontab详解
- 序列化和反序列化
- 将自己的本地项目上传到svn
- DDoS攻击和IP欺骗
- iOS:Compile error List(二)--Special
- 线上SQL优化
- jQuery serializeArray() 方法的一些注意事项
- linux下安装phpunit