题目链接: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):

 #include <bits/stdc++.h>
using namespace std; struct Node;
typedef shared_ptr<Node> Nptr;
//typedef Node* Nptr; struct Node {
Nptr lson, rson;
int size, weight;
char c;
void update() {
size = lson->size + rson->size + ;
}
};
Nptr nil; Nptr new_node(char c) {
Nptr x = Nptr(new Node);
x->lson = x->rson = nil;
x->size = ;
x->weight = rand();
x->c = c;
return x;
} Nptr new_node(char c, Nptr lson, Nptr rson) {
Nptr x = Nptr(new Node);
x->lson = lson;
x->rson = rson;
x->update();
x->weight = rand();
x->c = c;
return x;
} void initTreap() {
nil = Nptr(new Node);
nil->lson = nil->rson = nil;
nil->size = ;
} Nptr build(char *st, char *ed) {
if(st == ed) return nil;
assert(st < ed);
char *mid = st + (ed - st) / ;
return new_node(*mid, build(st, mid), build(mid + , ed));
} typedef pair<Nptr, Nptr> Ppp; Ppp split(Nptr x, int n) {
if(n == ) return make_pair(nil, x);
int ls = x->lson->size; if(ls >= n) {
Ppp a = split(x->lson, n);
return make_pair(a.first, new_node(x->c, a.second, x->rson));
} else {
Ppp a = split(x->rson, n - ls - );
return make_pair(new_node(x->c, x->lson, a.first), a.second);
}
} Nptr merge(Nptr a, Nptr b) {
if(a == nil) return b;
if(b == nil) return a;
if(a->weight < b->weight) {
return new_node(a->c, a->lson, merge(a->rson, b));
} else {
return new_node(b->c, merge(a, b->lson), b->rson);
}
} int print(Nptr x) {
if(x == nil) return ;
int res = (x->c == 'c');
res += print(x->lson);
putchar(x->c);
res += print(x->rson);
return res;
} Nptr insert(Nptr x, int pos, char s[]) {
Nptr a = build(s, s + strlen(s));
Ppp p = split(x, pos);
return merge(p.first, merge(a, p.second));
} Nptr remove(Nptr x, int pos, int len) {
Ppp a = split(x, pos);
Ppp b = split(a.second, len);
return merge(a.first, b.second);
} int print(Nptr x, int pos, int len) {
Ppp a = split(x, pos);
Ppp b = split(a.second, len);
int res = print(b.first);
puts("");
return res;
} Nptr rt[];
char s[];
int n, d, vnow; int main() {
initTreap();
rt[] = nil; scanf("%d", &n);
while(n--) {
int v, p, c, op;
scanf("%d", &op);
if(op == ) {
scanf("%d%s", &p, s);
p -= d;
vnow++;
rt[vnow] = insert(rt[vnow - ], p, s);
}
if(op == ) {
scanf("%d%d", &p, &c);
p -= d, c -= d;
vnow++;
rt[vnow] = remove(rt[vnow - ], p - , c);
}
if(op == ) {
scanf("%d%d%d", &v, &p, &c);
v -= d, p -= d, c -= d;
d += print(rt[v], p - , c);
}
}
}

代码(rope大法 322MS):

 #include <bits/stdc++.h>
#include <ext/rope>
using namespace std;
#define FOR(i, n) for(int i = 0; i < n; ++i) const int MAXN = ;
const int MAXS = ; __gnu_cxx::crope rt[MAXN], tmp; char s[MAXS];
int m, vnow, d; int main() {
scanf("%d", &m);
while(m--) {
int op, p, v, c;
scanf("%d", &op);
if(op == ) {
scanf("%d%s", &p, s);
p -= d;
rt[vnow + ] = rt[vnow];
rt[++vnow].insert(p, s);
} else if(op == ) {
scanf("%d%d", &p, &c);
p -= d, c -= d;
rt[vnow + ] = rt[vnow];
rt[++vnow].erase(p - , c);
} else if(op == ) {
scanf("%d%d%d", &v, &p, &c);
v -= d, p -= d, c -= d;
tmp = rt[v].substr(p - , c);
printf("%s\n", tmp.c_str());
d += count(tmp.begin(), tmp.end(), 'c');
}
}
}

UVALive 6145 Version Controlled IDE(可持久化treap、rope)的更多相关文章

  1. UVA - 12538 Version Controlled IDE (可持久化treap)

    紫薯例题 #include<bits/stdc++.h> using namespace std; typedef long long ll; ,inf=0x3f3f3f3f; ],ch[ ...

  2. UVA12538 Version Controlled IDE

    题意翻译 维护一种数据结构,资磁三种操作. 1.在p位置插入一个字符串s 2.从p位置开始删除长度为c的字符串 3.输出第v个历史版本中从p位置开始的长度为c的字符串 1≤n≤50000,所有字符串总 ...

  3. UVA 12538 Version Controlled IDE 解题报告

    题意:给三种操作 1.在p位置插入一个字符串. 2.从p位置开始删除长度为c的字符串 3.输出第v个历史版本中从p位置开始的长度为c的字符串 解法:可以用平衡树做,但是不会.后来又听说可一用一个叫ro ...

  4. BZOJ 3595: [Scoi2014]方伯伯的Oj SBT+可持久化Treap

    3595: [Scoi2014]方伯伯的Oj Time Limit: 6 Sec  Memory Limit: 256 MBSubmit: 102  Solved: 54[Submit][Status ...

  5. 【模板】可持久化文艺平衡树-可持久化treap

    题目链接 题意 对于各个以往的历史版本实现以下操作: 在第 p 个数后插入数 x . 删除第 p 个数. 翻转区间 [l,r],例如原序列是 \(\{5,4,3,2,1\}\),翻转区间 [2,4] ...

  6. 高rong效chang的可持久化treap

    很多人觉得可持久化treap很慢,但是事实上只是他们可持久化treap的写法不对.他们一般是用split和merge实现所有功能,但是这样会有许多不必要的分裂.其实我们可以用一种特殊的方式来实现插入和 ...

  7. 可持久化Treap

    终于写了一次可持久化Treap,做的是可持久化序列的模板题. Treap Treap=Tree+Heap,是一个随机化的数据结构.它的每个节点至少有两个关键字,一个是我们要存储的\(val\),一个是 ...

  8. Codeforces - 38G 可持久化Treap 区间操作

    题意:\(n\)个人排队,每个人有重要度\(p\)和不要脸度\(c\),如果第\(i\)个人的重要度大于第\(i-1\)个人的重要度,那么他们之间可以交换,不要脸度-1,交换后先前的第\(i\)个人也 ...

  9. Codeforces - 675D 可持久化Treap 树形操作

    题意:模拟二叉树的构造过程,给出\(n\)个节点,每次从根插入,小于当前节点转到左儿子,否则右儿子,输出第\([2,n]\)个节点的父亲的权值 直接手动模拟会被链式结构T掉 网上找了下发现二叉树的性质 ...

随机推荐

  1. Go 语言开发的基于 Linux 虚拟服务器的负载平衡平台 Seesaw

    负载均衡系统 Seesaw Seesaw是由我们网络可靠性工程师用 Go 语言开发的基于 Linux 虚拟服务器的负载平衡平台,就像所有好的项目一样,这个项目也是为了解决实际问题而产生的. Seesa ...

  2. 集合类(Objective-C & Swift)

    内容提要: 本文前两部分讲了Cocoa的集合类和Swift的集合类,其中Cocoa提供的集合类包括NSArray.NSMutableArray.NSDictionary.NSMutableDictio ...

  3. python装饰器方法

    前几天向几位新同事介绍项目,被问起了@login_required的实现,我说这是django框架提供的装饰器方法,验证用户是否登录,只要这样用就行了,因为自己不熟,并没有做过多解释. 今天查看dja ...

  4. xdebug和xhprof

    在安装时出现不是:1% 不是有效的win32 应用程序原因可能是是下载了64位的.dll扩展与当前的php不兼容

  5. 超爱http://www.runoob.com/菜鸟编程

    超爱http://www.runoob.com/菜鸟编程 http://www.runoob.com/

  6. Thinkpad E430 Ubuntu 14.04 无线网卡驱动

    为了重新安装正确的无线网卡的驱动,所以要先弄清楚我的笔记本上的无线网卡的具体的型号.打开终端,用如下命令/方法查看:lspci,找到输出信息中,有关无线网卡的部分.发现型号是:BCM43142 先用有 ...

  7. javascript [] 与 {} 的区别

    []是数组形式,{}是对象形式,都可以包含其他类型.如var a= ["A","B",{a:1,b:2}];a[1] 取得的是B,a[2].b取得的是2;var ...

  8. for循环计数

    1.巧用for循环计数,将文件每10行写到另一个文件,每遍历一行i就加1 with open('/etc/passwd') as f1, open('/tmp/passwd','w') as f2: ...

  9. [GeoServer]重拾GeoServer之安装篇

    GeoServer的项目是一个完整的Java(J2EE)系统,现实了OpenGIS联盟的网络功能服务器规范和网络覆盖服务器规范,并且集成了Web地图服务器. 在大三的时候WebGIS课程中老师讲解过一 ...

  10. python使用zlib实现压缩与解压字符串

    命令 字符串:使用zlib.compress可以压缩字符串.使用zlib.decompress可以解压字符串. 数据流:压缩:compressobj,解压:decompressobj 案例 >& ...