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掉 网上找了下发现二叉树的性质 ...
随机推荐
- Python之list添加新元素、删除元素、替换元素
Python之list添加新元素 现在,班里有3名同学: >>> L = ['Adam', 'Lisa', 'Bart'] 今天,班里转来一名新同学 Paul,如何把新同学添加到现有 ...
- C++ 简单中文敏感词检测工具类
具体思路: 1->敏感词库,可从数据库读取,也可以从文件加载. 2->将敏感词转化为gbk编码,因为gbk严格按照字符一个字节,汉字两个字节的格式编码,便于容易切分文字段. 3->将 ...
- sqlserver 中含有某字符串
查找 sqlserver 中字符串的ascii码SET TEXTSIZE 0-- Create variables for the character string and for the curre ...
- JS之setAttribute和getAttribute
1.ele.getAttribute(attributeName); 返回元素的指定属性值,如果元素没有该属性,则返回null 2.ele.setAttribute(attributeName,val ...
- Java学习-030-JSON 之四 -- 判断 JSONObject 是否包含键值对
前文对获取 JSON 数据封装方法,使之可通过类似于 cssSelector 的方法获取 JSON 数据,使获取数据变得简单.敬请参阅:模仿 cssSelector 封装读取 JSON 数据方法. 在 ...
- java时间戳转date(转)
1.时间戳的定义 时间戳(timestamp),通常是一个数字序列,唯一地标识某一刻的时间,指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起 ...
- Change Tracking of SQLServer
1.Enable the change tracking at the database level. ALTER DATABASE AdventureWorks2008 SET CHANGE_TRA ...
- bootstrap响应式布局简单实例
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8&quo ...
- zabbix配置发送报警邮件
配置邮件分为两种情况: 第一种:使用远端邮件服务器发送报警邮件 Linux系统版本:CentOS6.5-64 下载mailx: http://nchc.dl.sourceforge.net/proje ...
- TXT导入出现乱码
错误#1 11:15 2012-12-19客户提供一txt文本文件,要求导入到数据库,选用dts导入工具,选择数据源步骤如下列预览时出现乱码解答#1 双击打开原始文件中文显示正常,将其另存为选择编码为 ...