题目链接: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. jq窗口类小问题

    if ($(window).height() + $(window).scrollTop() >= $(document.body).height() - options.marginBotto ...

  2. Python中定义字符串

    字符串可以用''或者""括起来表示.如果字符串本身包含'怎么办?比如我们要表示字符串 I'm OK ,这时,可以用" "括起来表示: "I'm OK& ...

  3. 【Java 基础篇】【第五课】类的构造函数

    Java 也有自己的构造函数,如同c++一样有两个特征: 1.构造函数的名字和类的名字相同 2.构造函数没有返回值 下面来看一下这个例子: public class test { public sta ...

  4. ubuntu下hadoop环境配置

    软件环境: 虚拟机:VMware Workstation 10 操作系统:ubuntu-12.04-desktop-amd64 JAVA版本:jdk-7u55-linux-x64 Hadoop版本:h ...

  5. NAT原理与NAT穿越

    最近在看东西的时候发现很多网络程序中都需要NAT穿越,特意在此总结一下. 先做一个约定: 内网A中有:A1(192.168.0.8).A2(192.168.0.9)两用户 网关X1(一个NAT设备)有 ...

  6. Intervals---poj1201(差分约束系统)

    题目链接:http://poj.org/problem?id=1201 题目说[ai, bi]区间内和点集Z至少有ci个共同元素,那也就是说如果我用Si表示区间[0,i]区间内至少有多少个元素的话,那 ...

  7. [转]获得 LayoutInflater 实例的三种方式

    转自:http://www.cnblogs.com/androidez/archive/2013/07/01/3164729.html 获得 LayoutInflater 实例的三种方式   在实际开 ...

  8. 让DIV中的内容水平和垂直居中

    让一个层水平垂直居中是一个非常常见的布局方式,但在html中水平居中使用margin:0px auto;可以实现,但垂直居中使用外边距是无法达到效果的.(页面设置height:100%;是无效的),这 ...

  9. js数组判断是否含有某一个元素

    arr.indexOf('a')如果有则返回的a的下标位置,否则返回false.

  10. python3学习问题汇总

    1.python2脚本转python3报类型错误 TypeError: ‘str’ does not support the buffer interface 原因:Python3x的string类型 ...