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掉 网上找了下发现二叉树的性质 ...
随机推荐
- 蓝牙BLE LINK LAYER剖析(一) -- status and channel
一.LINK LAYER STATES 二.PHYSICAL CHANNEL
- https centos6 and 7
keytool -printcert -sslserver 10.10.192.90:8443 -rfc >nexus.crt 通过 openssl 将 证书转换为 .pem格式的 通过以下命 ...
- HBase的数据迁移(含HDFS的数据迁移)
1.启动两个HDFS集群 hadoop0,hadoop1,都是伪分布式的集群 2.启动hadoop3的zookeeper与hbase 注意点:需要开启yarn服务,因为distcp需要yarn. 3. ...
- scala 学习笔记
1.简洁 1.1.java的写法 class MyClass { private int index; private String name; public MyClass(int index, S ...
- Compiling Inkscape on Windows
http://wiki.inkscape.org/wiki/index.php/Compiling_Inkscape_on_Windows http://www.oschina.net/news/80 ...
- 其他常用HTML 片段
1.input placeholder 文字居中 字体大小+上下padding值等于设计稿宽度 设计稿中总高度为86px padding:27px 0;font-size:30px; 2.英文 ...
- ArcSDE for SQL Server安装及在ArcMap中创建ArcSDE连接
原文:ArcSDE for SQL Server安装及在ArcMap中创建ArcSDE连接 安装ArcSDE for SQL Server,最后一步成功后的界面如下: 在ArcMap中创建ArcSDE ...
- 使用Areas分离ASP.NET MVC项目
为什么需要分离? 我们知道MVC项目各部分职责比较清晰,相比较ASP.NET Webform而言,MVC项目的业务逻辑和页面展现较好地分离开来,这样的做法有许多优点,比如可测试,易扩展等等.但是在实际 ...
- undefined和void
1.undefined undefined在js中并不是关键字/保留字,因此在IE5.5~8中可以对undefined赋值,但是在IE9以上,对其赋值是无效的 <script> var a ...
- logback配置详解(二)
<appender> <appender>: <appender>是<configuration>的子节点,是负责写日志的组件. <appende ...