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):
#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)的更多相关文章
- UVA - 12538 Version Controlled IDE (可持久化treap)
紫薯例题 #include<bits/stdc++.h> using namespace std; typedef long long ll; ,inf=0x3f3f3f3f; ],ch[ ...
- UVA12538 Version Controlled IDE
题意翻译 维护一种数据结构,资磁三种操作. 1.在p位置插入一个字符串s 2.从p位置开始删除长度为c的字符串 3.输出第v个历史版本中从p位置开始的长度为c的字符串 1≤n≤50000,所有字符串总 ...
- UVA 12538 Version Controlled IDE 解题报告
题意:给三种操作 1.在p位置插入一个字符串. 2.从p位置开始删除长度为c的字符串 3.输出第v个历史版本中从p位置开始的长度为c的字符串 解法:可以用平衡树做,但是不会.后来又听说可一用一个叫ro ...
- BZOJ 3595: [Scoi2014]方伯伯的Oj SBT+可持久化Treap
3595: [Scoi2014]方伯伯的Oj Time Limit: 6 Sec Memory Limit: 256 MBSubmit: 102 Solved: 54[Submit][Status ...
- 【模板】可持久化文艺平衡树-可持久化treap
题目链接 题意 对于各个以往的历史版本实现以下操作: 在第 p 个数后插入数 x . 删除第 p 个数. 翻转区间 [l,r],例如原序列是 \(\{5,4,3,2,1\}\),翻转区间 [2,4] ...
- 高rong效chang的可持久化treap
很多人觉得可持久化treap很慢,但是事实上只是他们可持久化treap的写法不对.他们一般是用split和merge实现所有功能,但是这样会有许多不必要的分裂.其实我们可以用一种特殊的方式来实现插入和 ...
- 可持久化Treap
终于写了一次可持久化Treap,做的是可持久化序列的模板题. Treap Treap=Tree+Heap,是一个随机化的数据结构.它的每个节点至少有两个关键字,一个是我们要存储的\(val\),一个是 ...
- Codeforces - 38G 可持久化Treap 区间操作
题意:\(n\)个人排队,每个人有重要度\(p\)和不要脸度\(c\),如果第\(i\)个人的重要度大于第\(i-1\)个人的重要度,那么他们之间可以交换,不要脸度-1,交换后先前的第\(i\)个人也 ...
- Codeforces - 675D 可持久化Treap 树形操作
题意:模拟二叉树的构造过程,给出\(n\)个节点,每次从根插入,小于当前节点转到左儿子,否则右儿子,输出第\([2,n]\)个节点的父亲的权值 直接手动模拟会被链式结构T掉 网上找了下发现二叉树的性质 ...
随机推荐
- 20145319 《java程序设计》课程总结
20145319 <Java程序设计>课程总结 读书笔记链接总结 - 20145319 第一周学习总结 - 20145319 第二周学习总结 - 20145319 第三周学习总结 - 20 ...
- Android App罕见错误和优化方案
本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 1.App如果被定义一个有参数构造函数,那么需要再定义一个无参数的,如果不则会在某些情况下初始化失败 ...
- 转:ASP.NET MVC3 Model验证总结
http://www.wyjexplorer.cn/Post/2012/8/3/model-validation-in-aspnet-mvc3 ASP.NET MVC3中的Model是自验证的,这是通 ...
- js获取div中的文本框数据
通过div得到div里的所有数据 大神的世界无需解释,当然不是说我,当我看到这些代码的时候我惊呆了! 这是一个工具方法js: js: /* * 获取指定对象下的所有input.textarea值 * ...
- Android笔记:java 中的数组
在与嵌入式设备通讯的过程中使用的socket通讯 获取的字节流,通常转换为字节数组,需要根据协议将字节数组拆分.对于有规律的重复拆分可以使用,由于java中不能像c中直接进行内存操作例如使用struc ...
- SqlServer2008R2 如何插入多条数据
列id 为自增列 insert into Websites2values('Google','https://www.google.cm/','USA',1),('淘宝','https://www.t ...
- linux spi 设备节点 读写
本文记录spi设备节点的操作方法. SPI总线设备文件名通常为/dev/spidevN.P(N=0.1.2--,P=0.1.2--), 其中N表示第几路SPI总线,而P表示在该路SPI总线中使用哪个C ...
- iOS: 使用KVO监听控制器中数组的变化
一.介绍: KVO是一种能动态监听到属性值的改变的方式,使用场景非常广泛,这里我只讲如何监听控制器ViewController中数组的变化. 二.了解: 首先我们应该知道KVO是不能直接监听控制器Vi ...
- Power-BI:从5方面助力您企业的发展
商务智能让企业得以使用自己的数据来预测销量趋势.分析ROI.追踪收益.做出更明智的产品和服务决策.商务智能可从5个方面让您成为“数据之星”,为您发展企业: 1.关注企业成长.而非数据 优质的BI工具最 ...
- RFS_注释
1. 注释的操作如下: